1 /***************************************************************************/
5 /* FreeType utility file for memory and list management (body). */
7 /* Copyright 2002, 2004-2007, 2013 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_MEMORY_H
22 #include FT_INTERNAL_OBJECTS_H
26 /*************************************************************************/
28 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
29 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
30 /* messages during execution. */
33 #define FT_COMPONENT trace_memory
36 /*************************************************************************/
37 /*************************************************************************/
38 /*************************************************************************/
41 /***** M E M O R Y M A N A G E M E N T *****/
44 /*************************************************************************/
45 /*************************************************************************/
46 /*************************************************************************/
49 FT_BASE_DEF( FT_Pointer )
50 ft_mem_alloc( FT_Memory memory,
55 FT_Pointer block = ft_mem_qalloc( memory, size, &error );
57 if ( !error && size > 0 )
58 FT_MEM_ZERO( block, size );
65 FT_BASE_DEF( FT_Pointer )
66 ft_mem_qalloc( FT_Memory memory,
70 FT_Error error = FT_Err_Ok;
71 FT_Pointer block = NULL;
76 block = memory->alloc( memory, size );
78 error = FT_THROW( Out_Of_Memory );
82 /* may help catch/prevent security issues */
83 error = FT_THROW( Invalid_Argument );
91 FT_BASE_DEF( FT_Pointer )
92 ft_mem_realloc( FT_Memory memory,
99 FT_Error error = FT_Err_Ok;
102 block = ft_mem_qrealloc( memory, item_size,
103 cur_count, new_count, block, &error );
104 if ( !error && new_count > cur_count )
105 FT_MEM_ZERO( (char*)block + cur_count * item_size,
106 ( new_count - cur_count ) * item_size );
113 FT_BASE_DEF( FT_Pointer )
114 ft_mem_qrealloc( FT_Memory memory,
121 FT_Error error = FT_Err_Ok;
124 /* Note that we now accept `item_size == 0' as a valid parameter, in
125 * order to cover very weird cases where an ALLOC_MULT macro would be
128 if ( cur_count < 0 || new_count < 0 || item_size < 0 )
130 /* may help catch/prevent nasty security issues */
131 error = FT_THROW( Invalid_Argument );
133 else if ( new_count == 0 || item_size == 0 )
135 ft_mem_free( memory, block );
138 else if ( new_count > FT_INT_MAX/item_size )
140 error = FT_THROW( Array_Too_Large );
142 else if ( cur_count == 0 )
144 FT_ASSERT( block == NULL );
146 block = ft_mem_alloc( memory, new_count*item_size, &error );
151 FT_Long cur_size = cur_count*item_size;
152 FT_Long new_size = new_count*item_size;
155 block2 = memory->realloc( memory, cur_size, new_size, block );
156 if ( block2 == NULL )
157 error = FT_THROW( Out_Of_Memory );
168 ft_mem_free( FT_Memory memory,
172 memory->free( memory, (void*)P );
176 FT_BASE_DEF( FT_Pointer )
177 ft_mem_dup( FT_Memory memory,
183 FT_Pointer p = ft_mem_qalloc( memory, size, &error );
186 if ( !error && address )
187 ft_memcpy( p, address, size );
194 FT_BASE_DEF( FT_Pointer )
195 ft_mem_strdup( FT_Memory memory,
199 FT_ULong len = str ? (FT_ULong)ft_strlen( str ) + 1
203 return ft_mem_dup( memory, str, len, p_error );
207 FT_BASE_DEF( FT_Int )
208 ft_mem_strcpyn( char* dst,
212 while ( size > 1 && *src != 0 )
218 *dst = 0; /* always zero-terminate */
224 /*************************************************************************/
225 /*************************************************************************/
226 /*************************************************************************/
229 /***** D O U B L Y L I N K E D L I S T S *****/
232 /*************************************************************************/
233 /*************************************************************************/
234 /*************************************************************************/
237 #define FT_COMPONENT trace_list
239 /* documentation is in ftlist.h */
241 FT_EXPORT_DEF( FT_ListNode )
242 FT_List_Find( FT_List list,
254 if ( cur->data == data )
264 /* documentation is in ftlist.h */
266 FT_EXPORT_DEF( void )
267 FT_List_Add( FT_List list,
273 if ( !list || !node )
290 /* documentation is in ftlist.h */
292 FT_EXPORT_DEF( void )
293 FT_List_Insert( FT_List list,
299 if ( !list || !node )
316 /* documentation is in ftlist.h */
318 FT_EXPORT_DEF( void )
319 FT_List_Remove( FT_List list,
322 FT_ListNode before, after;
325 if ( !list || !node )
332 before->next = after;
337 after->prev = before;
343 /* documentation is in ftlist.h */
345 FT_EXPORT_DEF( void )
346 FT_List_Up( FT_List list,
349 FT_ListNode before, after;
352 if ( !list || !node )
358 /* check whether we are already on top of the list */
362 before->next = after;
365 after->prev = before;
370 node->next = list->head;
371 list->head->prev = node;
376 /* documentation is in ftlist.h */
378 FT_EXPORT_DEF( FT_Error )
379 FT_List_Iterate( FT_List list,
380 FT_List_Iterator iterator,
384 FT_Error error = FT_Err_Ok;
387 if ( !list || !iterator )
388 return FT_THROW( Invalid_Argument );
394 FT_ListNode next = cur->next;
397 error = iterator( cur, user );
408 /* documentation is in ftlist.h */
410 FT_EXPORT_DEF( void )
411 FT_List_Finalize( FT_List list,
412 FT_List_Destructor destroy,
419 if ( !list || !memory )
425 FT_ListNode next = cur->next;
426 void* data = cur->data;
430 destroy( memory, data, user );