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