1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ftutil.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* FreeType utility file for memory and list management (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 2002, 2004-2007, 2013 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include <ft2build.h> 20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_DEBUG_H 21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_MEMORY_H 22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_OBJECTS_H 23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_LIST_H 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_memory 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** M E M O R Y M A N A G E M E N T *****/ 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Pointer ) 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_alloc( FT_Memory memory, 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long size, 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error *p_error ) 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer block = ft_mem_qalloc( memory, size, &error ); 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error && size > 0 ) 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_ZERO( block, size ); 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p_error = error; 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return block; 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Pointer ) 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_qalloc( FT_Memory memory, 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long size, 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error *p_error ) 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer block = NULL; 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( size > 0 ) 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block = memory->alloc( memory, size ); 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( block == NULL ) 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Out_Of_Memory ); 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( size < 0 ) 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* may help catch/prevent security issues */ 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Argument ); 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p_error = error; 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return block; 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Pointer ) 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_realloc( FT_Memory memory, 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long item_size, 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long cur_count, 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long new_count, 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* block, 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error *p_error ) 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block = ft_mem_qrealloc( memory, item_size, 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur_count, new_count, block, &error ); 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error && new_count > cur_count ) 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_ZERO( (char*)block + cur_count * item_size, 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( new_count - cur_count ) * item_size ); 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p_error = error; 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return block; 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Pointer ) 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_qrealloc( FT_Memory memory, 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long item_size, 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long cur_count, 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long new_count, 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* block, 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error *p_error ) 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note that we now accept `item_size == 0' as a valid parameter, in 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * order to cover very weird cases where an ALLOC_MULT macro would be 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * called. 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur_count < 0 || new_count < 0 || item_size < 0 ) 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* may help catch/prevent nasty security issues */ 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Invalid_Argument ); 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( new_count == 0 || item_size == 0 ) 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_free( memory, block ); 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block = NULL; 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( new_count > FT_INT_MAX/item_size ) 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Array_Too_Large ); 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( cur_count == 0 ) 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ASSERT( block == NULL ); 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block = ft_mem_alloc( memory, new_count*item_size, &error ); 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer block2; 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long cur_size = cur_count*item_size; 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Long new_size = new_count*item_size; 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block2 = memory->realloc( memory, cur_size, new_size, block ); 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( block2 == NULL ) 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Out_Of_Memory ); 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov block = block2; 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p_error = error; 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return block; 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( void ) 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_free( FT_Memory memory, 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void *P ) 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( P ) 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memory->free( memory, (void*)P ); 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Pointer ) 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_dup( FT_Memory memory, 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* address, 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size, 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error *p_error ) 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Pointer p = ft_mem_qalloc( memory, size, &error ); 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error && address ) 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_memcpy( p, address, size ); 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *p_error = error; 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return p; 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Pointer ) 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_strdup( FT_Memory memory, 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* str, 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error *p_error ) 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong len = str ? (FT_ULong)ft_strlen( str ) + 1 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : 0; 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ft_mem_dup( memory, str, len, p_error ); 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BASE_DEF( FT_Int ) 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_mem_strcpyn( char* dst, 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* src, 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ULong size ) 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( size > 1 && *src != 0 ) 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *dst++ = *src++; 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size--; 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *dst = 0; /* always zero-terminate */ 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return *src != 0; 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** D O U B L Y L I N K E D L I S T S *****/ 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***** *****/ 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_list 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftlist.h */ 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_ListNode ) 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Find( FT_List list, 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* data ) 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode cur; 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 248e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !list ) 249e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return NULL; 250e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = list->head; 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur ) 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cur->data == data ) 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cur; 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = cur->next; 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 260e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return NULL; 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftlist.h */ 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( void ) 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Add( FT_List list, 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node ) 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 270e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_ListNode before; 271e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 272e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 273e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !list || !node ) 274e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 276e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov before = list->tail; 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->next = 0; 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->prev = before; 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( before ) 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov before->next = node; 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->head = node; 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->tail = node; 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftlist.h */ 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( void ) 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Insert( FT_List list, 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node ) 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 296e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_ListNode after; 297e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 298e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 299e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !list || !node ) 300e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 302e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov after = list->head; 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->next = after; 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->prev = 0; 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !after ) 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->tail = node; 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov after->prev = node; 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->head = node; 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftlist.h */ 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( void ) 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Remove( FT_List list, 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node ) 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode before, after; 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 325e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !list || !node ) 326e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 327e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov before = node->prev; 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov after = node->next; 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( before ) 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov before->next = after; 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->head = after; 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( after ) 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov after->prev = before; 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->tail = before; 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftlist.h */ 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( void ) 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Up( FT_List list, 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode node ) 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode before, after; 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 352e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !list || !node ) 353e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 354e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov before = node->prev; 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov after = node->next; 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check whether we are already on top of the list */ 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !before ) 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov before->next = after; 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( after ) 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov after->prev = before; 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->tail = before; 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->prev = 0; 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov node->next = list->head; 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->head->prev = node; 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->head = node; 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftlist.h */ 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( FT_Error ) 379e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_List_Iterate( FT_List list, 380e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_List_Iterator iterator, 381e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void* user ) 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 383e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_ListNode cur; 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error = FT_Err_Ok; 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 387e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !list || !iterator ) 388e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return FT_THROW( Invalid_Argument ); 389e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 390e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov cur = list->head; 391e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur ) 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode next = cur->next; 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = iterator( cur, user ); 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = next; 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* documentation is in ftlist.h */ 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_EXPORT_DEF( void ) 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Finalize( FT_List list, 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_List_Destructor destroy, 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory, 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* user ) 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode cur; 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 419e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !list || !memory ) 420e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 421e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = list->head; 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( cur ) 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ListNode next = cur->next; 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* data = cur->data; 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( destroy ) 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov destroy( memory, data, user ); 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( cur ); 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cur = next; 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->head = 0; 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov list->tail = 0; 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 442