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