1*37da2899SCharles.Forsyth /***************************************************************************/ 2*37da2899SCharles.Forsyth /* */ 3*37da2899SCharles.Forsyth /* ftutil.c */ 4*37da2899SCharles.Forsyth /* */ 5*37da2899SCharles.Forsyth /* FreeType utility file for memory and list management (body). */ 6*37da2899SCharles.Forsyth /* */ 7*37da2899SCharles.Forsyth /* Copyright 2002 by */ 8*37da2899SCharles.Forsyth /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9*37da2899SCharles.Forsyth /* */ 10*37da2899SCharles.Forsyth /* This file is part of the FreeType project, and may only be used, */ 11*37da2899SCharles.Forsyth /* modified, and distributed under the terms of the FreeType project */ 12*37da2899SCharles.Forsyth /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13*37da2899SCharles.Forsyth /* this file you indicate that you have read the license and */ 14*37da2899SCharles.Forsyth /* understand and accept it fully. */ 15*37da2899SCharles.Forsyth /* */ 16*37da2899SCharles.Forsyth /***************************************************************************/ 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsyth 19*37da2899SCharles.Forsyth #include <ft2build.h> 20*37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H 21*37da2899SCharles.Forsyth #include FT_INTERNAL_MEMORY_H 22*37da2899SCharles.Forsyth #include FT_LIST_H 23*37da2899SCharles.Forsyth 24*37da2899SCharles.Forsyth 25*37da2899SCharles.Forsyth /*************************************************************************/ 26*37da2899SCharles.Forsyth /* */ 27*37da2899SCharles.Forsyth /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 28*37da2899SCharles.Forsyth /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 29*37da2899SCharles.Forsyth /* messages during execution. */ 30*37da2899SCharles.Forsyth /* */ 31*37da2899SCharles.Forsyth #undef FT_COMPONENT 32*37da2899SCharles.Forsyth #define FT_COMPONENT trace_memory 33*37da2899SCharles.Forsyth 34*37da2899SCharles.Forsyth 35*37da2899SCharles.Forsyth /*************************************************************************/ 36*37da2899SCharles.Forsyth /*************************************************************************/ 37*37da2899SCharles.Forsyth /*************************************************************************/ 38*37da2899SCharles.Forsyth /***** *****/ 39*37da2899SCharles.Forsyth /***** *****/ 40*37da2899SCharles.Forsyth /***** M E M O R Y M A N A G E M E N T *****/ 41*37da2899SCharles.Forsyth /***** *****/ 42*37da2899SCharles.Forsyth /***** *****/ 43*37da2899SCharles.Forsyth /*************************************************************************/ 44*37da2899SCharles.Forsyth /*************************************************************************/ 45*37da2899SCharles.Forsyth /*************************************************************************/ 46*37da2899SCharles.Forsyth 47*37da2899SCharles.Forsyth /* documentation is in ftmemory.h */ 48*37da2899SCharles.Forsyth 49*37da2899SCharles.Forsyth FT_BASE_DEF( FT_Error ) FT_Alloc(FT_Memory memory,FT_Long size,void ** P)50*37da2899SCharles.Forsyth FT_Alloc( FT_Memory memory, 51*37da2899SCharles.Forsyth FT_Long size, 52*37da2899SCharles.Forsyth void* *P ) 53*37da2899SCharles.Forsyth { 54*37da2899SCharles.Forsyth FT_ASSERT( P != 0 ); 55*37da2899SCharles.Forsyth 56*37da2899SCharles.Forsyth if ( size > 0 ) 57*37da2899SCharles.Forsyth { 58*37da2899SCharles.Forsyth *P = memory->alloc( memory, size ); 59*37da2899SCharles.Forsyth if ( !*P ) 60*37da2899SCharles.Forsyth { 61*37da2899SCharles.Forsyth FT_ERROR(( "FT_Alloc:" )); 62*37da2899SCharles.Forsyth FT_ERROR(( " Out of memory? (%ld requested)\n", 63*37da2899SCharles.Forsyth size )); 64*37da2899SCharles.Forsyth 65*37da2899SCharles.Forsyth return FT_Err_Out_Of_Memory; 66*37da2899SCharles.Forsyth } 67*37da2899SCharles.Forsyth FT_MEM_ZERO( *P, size ); 68*37da2899SCharles.Forsyth } 69*37da2899SCharles.Forsyth else 70*37da2899SCharles.Forsyth *P = NULL; 71*37da2899SCharles.Forsyth 72*37da2899SCharles.Forsyth FT_TRACE7(( "FT_Alloc:" )); 73*37da2899SCharles.Forsyth FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n", 74*37da2899SCharles.Forsyth size, *P, P )); 75*37da2899SCharles.Forsyth 76*37da2899SCharles.Forsyth return FT_Err_Ok; 77*37da2899SCharles.Forsyth } 78*37da2899SCharles.Forsyth 79*37da2899SCharles.Forsyth 80*37da2899SCharles.Forsyth /* documentation is in ftmemory.h */ 81*37da2899SCharles.Forsyth 82*37da2899SCharles.Forsyth FT_BASE_DEF( FT_Error ) FT_Realloc(FT_Memory memory,FT_Long current,FT_Long size,void ** P)83*37da2899SCharles.Forsyth FT_Realloc( FT_Memory memory, 84*37da2899SCharles.Forsyth FT_Long current, 85*37da2899SCharles.Forsyth FT_Long size, 86*37da2899SCharles.Forsyth void** P ) 87*37da2899SCharles.Forsyth { 88*37da2899SCharles.Forsyth void* Q; 89*37da2899SCharles.Forsyth 90*37da2899SCharles.Forsyth 91*37da2899SCharles.Forsyth FT_ASSERT( P != 0 ); 92*37da2899SCharles.Forsyth 93*37da2899SCharles.Forsyth /* if the original pointer is NULL, call FT_Alloc() */ 94*37da2899SCharles.Forsyth if ( !*P ) 95*37da2899SCharles.Forsyth return FT_Alloc( memory, size, P ); 96*37da2899SCharles.Forsyth 97*37da2899SCharles.Forsyth /* if the new block if zero-sized, clear the current one */ 98*37da2899SCharles.Forsyth if ( size <= 0 ) 99*37da2899SCharles.Forsyth { 100*37da2899SCharles.Forsyth FT_Free( memory, P ); 101*37da2899SCharles.Forsyth return FT_Err_Ok; 102*37da2899SCharles.Forsyth } 103*37da2899SCharles.Forsyth 104*37da2899SCharles.Forsyth Q = memory->realloc( memory, current, size, *P ); 105*37da2899SCharles.Forsyth if ( !Q ) 106*37da2899SCharles.Forsyth goto Fail; 107*37da2899SCharles.Forsyth 108*37da2899SCharles.Forsyth if ( size > current ) 109*37da2899SCharles.Forsyth FT_MEM_ZERO( (char*)Q + current, size - current ); 110*37da2899SCharles.Forsyth 111*37da2899SCharles.Forsyth *P = Q; 112*37da2899SCharles.Forsyth return FT_Err_Ok; 113*37da2899SCharles.Forsyth 114*37da2899SCharles.Forsyth Fail: 115*37da2899SCharles.Forsyth FT_ERROR(( "FT_Realloc:" )); 116*37da2899SCharles.Forsyth FT_ERROR(( " Failed (current %ld, requested %ld)\n", 117*37da2899SCharles.Forsyth current, size )); 118*37da2899SCharles.Forsyth return FT_Err_Out_Of_Memory; 119*37da2899SCharles.Forsyth } 120*37da2899SCharles.Forsyth 121*37da2899SCharles.Forsyth 122*37da2899SCharles.Forsyth /* documentation is in ftmemory.h */ 123*37da2899SCharles.Forsyth 124*37da2899SCharles.Forsyth FT_BASE_DEF( void ) FT_Free(FT_Memory memory,void ** P)125*37da2899SCharles.Forsyth FT_Free( FT_Memory memory, 126*37da2899SCharles.Forsyth void** P ) 127*37da2899SCharles.Forsyth { 128*37da2899SCharles.Forsyth FT_TRACE7(( "FT_Free:" )); 129*37da2899SCharles.Forsyth FT_TRACE7(( " Freeing block 0x%08p, ref 0x%08p\n", 130*37da2899SCharles.Forsyth P, P ? *P : (void*)0 )); 131*37da2899SCharles.Forsyth 132*37da2899SCharles.Forsyth if ( P && *P ) 133*37da2899SCharles.Forsyth { 134*37da2899SCharles.Forsyth memory->free( memory, *P ); 135*37da2899SCharles.Forsyth *P = 0; 136*37da2899SCharles.Forsyth } 137*37da2899SCharles.Forsyth } 138*37da2899SCharles.Forsyth 139*37da2899SCharles.Forsyth 140*37da2899SCharles.Forsyth /*************************************************************************/ 141*37da2899SCharles.Forsyth /*************************************************************************/ 142*37da2899SCharles.Forsyth /*************************************************************************/ 143*37da2899SCharles.Forsyth /***** *****/ 144*37da2899SCharles.Forsyth /***** *****/ 145*37da2899SCharles.Forsyth /***** D O U B L Y L I N K E D L I S T S *****/ 146*37da2899SCharles.Forsyth /***** *****/ 147*37da2899SCharles.Forsyth /***** *****/ 148*37da2899SCharles.Forsyth /*************************************************************************/ 149*37da2899SCharles.Forsyth /*************************************************************************/ 150*37da2899SCharles.Forsyth /*************************************************************************/ 151*37da2899SCharles.Forsyth 152*37da2899SCharles.Forsyth #undef FT_COMPONENT 153*37da2899SCharles.Forsyth #define FT_COMPONENT trace_list 154*37da2899SCharles.Forsyth 155*37da2899SCharles.Forsyth /* documentation is in ftlist.h */ 156*37da2899SCharles.Forsyth 157*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_ListNode ) FT_List_Find(FT_List list,void * data)158*37da2899SCharles.Forsyth FT_List_Find( FT_List list, 159*37da2899SCharles.Forsyth void* data ) 160*37da2899SCharles.Forsyth { 161*37da2899SCharles.Forsyth FT_ListNode cur; 162*37da2899SCharles.Forsyth 163*37da2899SCharles.Forsyth 164*37da2899SCharles.Forsyth cur = list->head; 165*37da2899SCharles.Forsyth while ( cur ) 166*37da2899SCharles.Forsyth { 167*37da2899SCharles.Forsyth if ( cur->data == data ) 168*37da2899SCharles.Forsyth return cur; 169*37da2899SCharles.Forsyth 170*37da2899SCharles.Forsyth cur = cur->next; 171*37da2899SCharles.Forsyth } 172*37da2899SCharles.Forsyth 173*37da2899SCharles.Forsyth return (FT_ListNode)0; 174*37da2899SCharles.Forsyth } 175*37da2899SCharles.Forsyth 176*37da2899SCharles.Forsyth 177*37da2899SCharles.Forsyth /* documentation is in ftlist.h */ 178*37da2899SCharles.Forsyth 179*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_List_Add(FT_List list,FT_ListNode node)180*37da2899SCharles.Forsyth FT_List_Add( FT_List list, 181*37da2899SCharles.Forsyth FT_ListNode node ) 182*37da2899SCharles.Forsyth { 183*37da2899SCharles.Forsyth FT_ListNode before = list->tail; 184*37da2899SCharles.Forsyth 185*37da2899SCharles.Forsyth 186*37da2899SCharles.Forsyth node->next = 0; 187*37da2899SCharles.Forsyth node->prev = before; 188*37da2899SCharles.Forsyth 189*37da2899SCharles.Forsyth if ( before ) 190*37da2899SCharles.Forsyth before->next = node; 191*37da2899SCharles.Forsyth else 192*37da2899SCharles.Forsyth list->head = node; 193*37da2899SCharles.Forsyth 194*37da2899SCharles.Forsyth list->tail = node; 195*37da2899SCharles.Forsyth } 196*37da2899SCharles.Forsyth 197*37da2899SCharles.Forsyth 198*37da2899SCharles.Forsyth /* documentation is in ftlist.h */ 199*37da2899SCharles.Forsyth 200*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_List_Insert(FT_List list,FT_ListNode node)201*37da2899SCharles.Forsyth FT_List_Insert( FT_List list, 202*37da2899SCharles.Forsyth FT_ListNode node ) 203*37da2899SCharles.Forsyth { 204*37da2899SCharles.Forsyth FT_ListNode after = list->head; 205*37da2899SCharles.Forsyth 206*37da2899SCharles.Forsyth 207*37da2899SCharles.Forsyth node->next = after; 208*37da2899SCharles.Forsyth node->prev = 0; 209*37da2899SCharles.Forsyth 210*37da2899SCharles.Forsyth if ( !after ) 211*37da2899SCharles.Forsyth list->tail = node; 212*37da2899SCharles.Forsyth else 213*37da2899SCharles.Forsyth after->prev = node; 214*37da2899SCharles.Forsyth 215*37da2899SCharles.Forsyth list->head = node; 216*37da2899SCharles.Forsyth } 217*37da2899SCharles.Forsyth 218*37da2899SCharles.Forsyth 219*37da2899SCharles.Forsyth /* documentation is in ftlist.h */ 220*37da2899SCharles.Forsyth 221*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_List_Remove(FT_List list,FT_ListNode node)222*37da2899SCharles.Forsyth FT_List_Remove( FT_List list, 223*37da2899SCharles.Forsyth FT_ListNode node ) 224*37da2899SCharles.Forsyth { 225*37da2899SCharles.Forsyth FT_ListNode before, after; 226*37da2899SCharles.Forsyth 227*37da2899SCharles.Forsyth 228*37da2899SCharles.Forsyth before = node->prev; 229*37da2899SCharles.Forsyth after = node->next; 230*37da2899SCharles.Forsyth 231*37da2899SCharles.Forsyth if ( before ) 232*37da2899SCharles.Forsyth before->next = after; 233*37da2899SCharles.Forsyth else 234*37da2899SCharles.Forsyth list->head = after; 235*37da2899SCharles.Forsyth 236*37da2899SCharles.Forsyth if ( after ) 237*37da2899SCharles.Forsyth after->prev = before; 238*37da2899SCharles.Forsyth else 239*37da2899SCharles.Forsyth list->tail = before; 240*37da2899SCharles.Forsyth } 241*37da2899SCharles.Forsyth 242*37da2899SCharles.Forsyth 243*37da2899SCharles.Forsyth /* documentation is in ftlist.h */ 244*37da2899SCharles.Forsyth 245*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_List_Up(FT_List list,FT_ListNode node)246*37da2899SCharles.Forsyth FT_List_Up( FT_List list, 247*37da2899SCharles.Forsyth FT_ListNode node ) 248*37da2899SCharles.Forsyth { 249*37da2899SCharles.Forsyth FT_ListNode before, after; 250*37da2899SCharles.Forsyth 251*37da2899SCharles.Forsyth 252*37da2899SCharles.Forsyth before = node->prev; 253*37da2899SCharles.Forsyth after = node->next; 254*37da2899SCharles.Forsyth 255*37da2899SCharles.Forsyth /* check whether we are already on top of the list */ 256*37da2899SCharles.Forsyth if ( !before ) 257*37da2899SCharles.Forsyth return; 258*37da2899SCharles.Forsyth 259*37da2899SCharles.Forsyth before->next = after; 260*37da2899SCharles.Forsyth 261*37da2899SCharles.Forsyth if ( after ) 262*37da2899SCharles.Forsyth after->prev = before; 263*37da2899SCharles.Forsyth else 264*37da2899SCharles.Forsyth list->tail = before; 265*37da2899SCharles.Forsyth 266*37da2899SCharles.Forsyth node->prev = 0; 267*37da2899SCharles.Forsyth node->next = list->head; 268*37da2899SCharles.Forsyth list->head->prev = node; 269*37da2899SCharles.Forsyth list->head = node; 270*37da2899SCharles.Forsyth } 271*37da2899SCharles.Forsyth 272*37da2899SCharles.Forsyth 273*37da2899SCharles.Forsyth /* documentation is in ftlist.h */ 274*37da2899SCharles.Forsyth 275*37da2899SCharles.Forsyth FT_EXPORT_DEF( FT_Error ) FT_List_Iterate(FT_List list,FT_List_Iterator iterator,void * user)276*37da2899SCharles.Forsyth FT_List_Iterate( FT_List list, 277*37da2899SCharles.Forsyth FT_List_Iterator iterator, 278*37da2899SCharles.Forsyth void* user ) 279*37da2899SCharles.Forsyth { 280*37da2899SCharles.Forsyth FT_ListNode cur = list->head; 281*37da2899SCharles.Forsyth FT_Error error = FT_Err_Ok; 282*37da2899SCharles.Forsyth 283*37da2899SCharles.Forsyth 284*37da2899SCharles.Forsyth while ( cur ) 285*37da2899SCharles.Forsyth { 286*37da2899SCharles.Forsyth FT_ListNode next = cur->next; 287*37da2899SCharles.Forsyth 288*37da2899SCharles.Forsyth 289*37da2899SCharles.Forsyth error = iterator( cur, user ); 290*37da2899SCharles.Forsyth if ( error ) 291*37da2899SCharles.Forsyth break; 292*37da2899SCharles.Forsyth 293*37da2899SCharles.Forsyth cur = next; 294*37da2899SCharles.Forsyth } 295*37da2899SCharles.Forsyth 296*37da2899SCharles.Forsyth return error; 297*37da2899SCharles.Forsyth } 298*37da2899SCharles.Forsyth 299*37da2899SCharles.Forsyth 300*37da2899SCharles.Forsyth /* documentation is in ftlist.h */ 301*37da2899SCharles.Forsyth 302*37da2899SCharles.Forsyth FT_EXPORT_DEF( void ) FT_List_Finalize(FT_List list,FT_List_Destructor destroy,FT_Memory memory,void * user)303*37da2899SCharles.Forsyth FT_List_Finalize( FT_List list, 304*37da2899SCharles.Forsyth FT_List_Destructor destroy, 305*37da2899SCharles.Forsyth FT_Memory memory, 306*37da2899SCharles.Forsyth void* user ) 307*37da2899SCharles.Forsyth { 308*37da2899SCharles.Forsyth FT_ListNode cur; 309*37da2899SCharles.Forsyth 310*37da2899SCharles.Forsyth 311*37da2899SCharles.Forsyth cur = list->head; 312*37da2899SCharles.Forsyth while ( cur ) 313*37da2899SCharles.Forsyth { 314*37da2899SCharles.Forsyth FT_ListNode next = cur->next; 315*37da2899SCharles.Forsyth void* data = cur->data; 316*37da2899SCharles.Forsyth 317*37da2899SCharles.Forsyth 318*37da2899SCharles.Forsyth if ( destroy ) 319*37da2899SCharles.Forsyth destroy( memory, data, user ); 320*37da2899SCharles.Forsyth 321*37da2899SCharles.Forsyth FT_FREE( cur ); 322*37da2899SCharles.Forsyth cur = next; 323*37da2899SCharles.Forsyth } 324*37da2899SCharles.Forsyth 325*37da2899SCharles.Forsyth list->head = 0; 326*37da2899SCharles.Forsyth list->tail = 0; 327*37da2899SCharles.Forsyth } 328*37da2899SCharles.Forsyth 329*37da2899SCharles.Forsyth 330*37da2899SCharles.Forsyth /* END */ 331