Home | History | Annotate | Download | only in internal
      1 /****************************************************************************
      2  *
      3  * ftmemory.h
      4  *
      5  *   The FreeType memory management macros (specification).
      6  *
      7  * Copyright 1996-2018 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 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   /*
     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 {
     70   template <typename T> inline T*
     71   cplusplus_typeof(        T*,
     72                     void  *v )
     73   {
     74     return static_cast <T*> ( v );
     75   }
     76 }
     77 
     78 #define FT_ASSIGNP( p, val )  (p) = cplusplus_typeof( (p), (val) )
     79 
     80 #else
     81 
     82 #define FT_ASSIGNP( p, val )  (p) = (val)
     83 
     84 #endif
     85 
     86 
     87 
     88 #ifdef FT_DEBUG_MEMORY
     89 
     90   FT_BASE( const char* )  _ft_debug_file;
     91   FT_BASE( long )         _ft_debug_lineno;
     92 
     93 #define FT_DEBUG_INNER( exp )  ( _ft_debug_file   = __FILE__, \
     94                                  _ft_debug_lineno = __LINE__, \
     95                                  (exp) )
     96 
     97 #define FT_ASSIGNP_INNER( p, exp )  ( _ft_debug_file   = __FILE__, \
     98                                       _ft_debug_lineno = __LINE__, \
     99                                       FT_ASSIGNP( p, exp ) )
    100 
    101 #else /* !FT_DEBUG_MEMORY */
    102 
    103 #define FT_DEBUG_INNER( exp )       (exp)
    104 #define FT_ASSIGNP_INNER( p, exp )  FT_ASSIGNP( p, exp )
    105 
    106 #endif /* !FT_DEBUG_MEMORY */
    107 
    108 
    109   /*
    110    * The allocation functions return a pointer, and the error code
    111    * is written to through the `p_error' parameter.
    112    */
    113 
    114   /* The `q' variants of the functions below (`q' for `quick') don't fill */
    115   /* the allocated or reallocated memory with zero bytes.                 */
    116 
    117   FT_BASE( FT_Pointer )
    118   ft_mem_alloc( FT_Memory  memory,
    119                 FT_Long    size,
    120                 FT_Error  *p_error );
    121 
    122   FT_BASE( FT_Pointer )
    123   ft_mem_qalloc( FT_Memory  memory,
    124                  FT_Long    size,
    125                  FT_Error  *p_error );
    126 
    127   FT_BASE( FT_Pointer )
    128   ft_mem_realloc( FT_Memory  memory,
    129                   FT_Long    item_size,
    130                   FT_Long    cur_count,
    131                   FT_Long    new_count,
    132                   void*      block,
    133                   FT_Error  *p_error );
    134 
    135   FT_BASE( FT_Pointer )
    136   ft_mem_qrealloc( FT_Memory  memory,
    137                    FT_Long    item_size,
    138                    FT_Long    cur_count,
    139                    FT_Long    new_count,
    140                    void*      block,
    141                    FT_Error  *p_error );
    142 
    143   FT_BASE( void )
    144   ft_mem_free( FT_Memory    memory,
    145                const void*  P );
    146 
    147 
    148   /* The `Q' variants of the macros below (`Q' for `quick') don't fill */
    149   /* the allocated or reallocated memory with zero bytes.              */
    150 
    151 #define FT_MEM_ALLOC( ptr, size )                               \
    152           FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory,          \
    153                                                (FT_Long)(size), \
    154                                                &error ) )
    155 
    156 #define FT_MEM_FREE( ptr )                \
    157           FT_BEGIN_STMNT                  \
    158             ft_mem_free( memory, (ptr) ); \
    159             (ptr) = NULL;                 \
    160           FT_END_STMNT
    161 
    162 #define FT_MEM_NEW( ptr )                        \
    163           FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) )
    164 
    165 #define FT_MEM_REALLOC( ptr, cursz, newsz )                        \
    166           FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory,           \
    167                                                  1,                \
    168                                                  (FT_Long)(cursz), \
    169                                                  (FT_Long)(newsz), \
    170                                                  (ptr),            \
    171                                                  &error ) )
    172 
    173 #define FT_MEM_QALLOC( ptr, size )                               \
    174           FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory,          \
    175                                                 (FT_Long)(size), \
    176                                                 &error ) )
    177 
    178 #define FT_MEM_QNEW( ptr )                        \
    179           FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) )
    180 
    181 #define FT_MEM_QREALLOC( ptr, cursz, newsz )                        \
    182           FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory,           \
    183                                                   1,                \
    184                                                   (FT_Long)(cursz), \
    185                                                   (FT_Long)(newsz), \
    186                                                   (ptr),            \
    187                                                   &error ) )
    188 
    189 #define FT_MEM_ALLOC_MULT( ptr, count, item_size )                     \
    190           FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory,               \
    191                                                  (FT_Long)(item_size), \
    192                                                  0,                    \
    193                                                  (FT_Long)(count),     \
    194                                                  NULL,                 \
    195                                                  &error ) )
    196 
    197 #define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz )           \
    198           FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory,            \
    199                                                  (FT_Long)(itmsz),  \
    200                                                  (FT_Long)(oldcnt), \
    201                                                  (FT_Long)(newcnt), \
    202                                                  (ptr),             \
    203                                                  &error ) )
    204 
    205 #define FT_MEM_QALLOC_MULT( ptr, count, item_size )                     \
    206           FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory,               \
    207                                                   (FT_Long)(item_size), \
    208                                                   0,                    \
    209                                                   (FT_Long)(count),     \
    210                                                   NULL,                 \
    211                                                   &error ) )
    212 
    213 #define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz )           \
    214           FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory,            \
    215                                                   (FT_Long)(itmsz),  \
    216                                                   (FT_Long)(oldcnt), \
    217                                                   (FT_Long)(newcnt), \
    218                                                   (ptr),             \
    219                                                   &error ) )
    220 
    221 
    222 #define FT_MEM_SET_ERROR( cond )  ( (cond), error != 0 )
    223 
    224 
    225 #define FT_MEM_SET( dest, byte, count )               \
    226           ft_memset( dest, byte, (FT_Offset)(count) )
    227 
    228 #define FT_MEM_COPY( dest, source, count )              \
    229           ft_memcpy( dest, source, (FT_Offset)(count) )
    230 
    231 #define FT_MEM_MOVE( dest, source, count )               \
    232           ft_memmove( dest, source, (FT_Offset)(count) )
    233 
    234 
    235 #define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )
    236 
    237 #define FT_ZERO( p )                FT_MEM_ZERO( p, sizeof ( *(p) ) )
    238 
    239 
    240 #define FT_ARRAY_ZERO( dest, count )                             \
    241           FT_MEM_ZERO( dest,                                     \
    242                        (FT_Offset)(count) * sizeof ( *(dest) ) )
    243 
    244 #define FT_ARRAY_COPY( dest, source, count )                     \
    245           FT_MEM_COPY( dest,                                     \
    246                        source,                                   \
    247                        (FT_Offset)(count) * sizeof ( *(dest) ) )
    248 
    249 #define FT_ARRAY_MOVE( dest, source, count )                     \
    250           FT_MEM_MOVE( dest,                                     \
    251                        source,                                   \
    252                        (FT_Offset)(count) * sizeof ( *(dest) ) )
    253 
    254 
    255   /*
    256    * Return the maximum number of addressable elements in an array.
    257    * We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid
    258    * any problems.
    259    */
    260 #define FT_ARRAY_MAX( ptr )           ( FT_INT_MAX / sizeof ( *(ptr) ) )
    261 
    262 #define FT_ARRAY_CHECK( ptr, count )  ( (count) <= FT_ARRAY_MAX( ptr ) )
    263 
    264 
    265   /**************************************************************************
    266    *
    267    * The following functions macros expect that their pointer argument is
    268    * _typed_ in order to automatically compute array element sizes.
    269    */
    270 
    271 #define FT_MEM_NEW_ARRAY( ptr, count )                              \
    272           FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory,            \
    273                                                  sizeof ( *(ptr) ), \
    274                                                  0,                 \
    275                                                  (FT_Long)(count),  \
    276                                                  NULL,              \
    277                                                  &error ) )
    278 
    279 #define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz )                     \
    280           FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory,            \
    281                                                  sizeof ( *(ptr) ), \
    282                                                  (FT_Long)(cursz),  \
    283                                                  (FT_Long)(newsz),  \
    284                                                  (ptr),             \
    285                                                  &error ) )
    286 
    287 #define FT_MEM_QNEW_ARRAY( ptr, count )                              \
    288           FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory,            \
    289                                                   sizeof ( *(ptr) ), \
    290                                                   0,                 \
    291                                                   (FT_Long)(count),  \
    292                                                   NULL,              \
    293                                                   &error ) )
    294 
    295 #define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz )                     \
    296           FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory,            \
    297                                                   sizeof ( *(ptr) ), \
    298                                                   (FT_Long)(cursz),  \
    299                                                   (FT_Long)(newsz),  \
    300                                                   (ptr),             \
    301                                                   &error ) )
    302 
    303 #define FT_ALLOC( ptr, size )                           \
    304           FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) )
    305 
    306 #define FT_REALLOC( ptr, cursz, newsz )                           \
    307           FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) )
    308 
    309 #define FT_ALLOC_MULT( ptr, count, item_size )                           \
    310           FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) )
    311 
    312 #define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz )              \
    313           FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt,      \
    314                                                  newcnt, itmsz ) )
    315 
    316 #define FT_QALLOC( ptr, size )                           \
    317           FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) )
    318 
    319 #define FT_QREALLOC( ptr, cursz, newsz )                           \
    320           FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) )
    321 
    322 #define FT_QALLOC_MULT( ptr, count, item_size )                           \
    323           FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) )
    324 
    325 #define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz )              \
    326           FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt,      \
    327                                                   newcnt, itmsz ) )
    328 
    329 #define FT_FREE( ptr )  FT_MEM_FREE( ptr )
    330 
    331 #define FT_NEW( ptr )  FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) )
    332 
    333 #define FT_NEW_ARRAY( ptr, count )                           \
    334           FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) )
    335 
    336 #define FT_RENEW_ARRAY( ptr, curcnt, newcnt )                           \
    337           FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )
    338 
    339 #define FT_QNEW( ptr )                           \
    340           FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) )
    341 
    342 #define FT_QNEW_ARRAY( ptr, count )                          \
    343           FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) )
    344 
    345 #define FT_QRENEW_ARRAY( ptr, curcnt, newcnt )                          \
    346           FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) )
    347 
    348 
    349   FT_BASE( FT_Pointer )
    350   ft_mem_strdup( FT_Memory    memory,
    351                  const char*  str,
    352                  FT_Error    *p_error );
    353 
    354   FT_BASE( FT_Pointer )
    355   ft_mem_dup( FT_Memory    memory,
    356               const void*  address,
    357               FT_ULong     size,
    358               FT_Error    *p_error );
    359 
    360 
    361 #define FT_MEM_STRDUP( dst, str )                                            \
    362           (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error )
    363 
    364 #define FT_STRDUP( dst, str )                           \
    365           FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) )
    366 
    367 #define FT_MEM_DUP( dst, address, size )                                    \
    368           (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error )
    369 
    370 #define FT_DUP( dst, address, size )                           \
    371           FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) )
    372 
    373 
    374   /* Return >= 1 if a truncation occurs.            */
    375   /* Return 0 if the source string fits the buffer. */
    376   /* This is *not* the same as strlcpy().           */
    377   FT_BASE( FT_Int )
    378   ft_mem_strcpyn( char*        dst,
    379                   const char*  src,
    380                   FT_ULong     size );
    381 
    382 #define FT_STRCPYN( dst, src, size )                                         \
    383           ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) )
    384 
    385  /* */
    386 
    387 
    388 FT_END_HEADER
    389 
    390 #endif /* FTMEMORY_H_ */
    391 
    392 
    393 /* END */
    394