Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenftutil.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* ftutil.c */ 00004 /* */ 00005 /* FreeType utility file for memory and list management (body). */ 00006 /* */ 00007 /* Copyright 2002, 2004, 2005, 2006, 2007 by */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 00015 /* */ 00016 /***************************************************************************/ 00017 00018 00019 #include <ft2build.h> 00020 #include FT_INTERNAL_DEBUG_H 00021 #include FT_INTERNAL_MEMORY_H 00022 #include FT_INTERNAL_OBJECTS_H 00023 #include FT_LIST_H 00024 00025 00026 /*************************************************************************/ 00027 /* */ 00028 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00029 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00030 /* messages during execution. */ 00031 /* */ 00032 #undef FT_COMPONENT 00033 #define FT_COMPONENT trace_memory 00034 00035 00036 /*************************************************************************/ 00037 /*************************************************************************/ 00038 /*************************************************************************/ 00039 /***** *****/ 00040 /***** *****/ 00041 /***** M E M O R Y M A N A G E M E N T *****/ 00042 /***** *****/ 00043 /***** *****/ 00044 /*************************************************************************/ 00045 /*************************************************************************/ 00046 /*************************************************************************/ 00047 00048 00049 FT_BASE_DEF( FT_Pointer ) 00050 ft_mem_alloc( FT_Memory memory, 00051 FT_Long size, 00052 FT_Error *p_error ) 00053 { 00054 FT_Error error; 00055 FT_Pointer block = ft_mem_qalloc( memory, size, &error ); 00056 00057 if ( !error && size > 0 ) 00058 FT_MEM_ZERO( block, size ); 00059 00060 *p_error = error; 00061 return block; 00062 } 00063 00064 00065 FT_BASE_DEF( FT_Pointer ) 00066 ft_mem_qalloc( FT_Memory memory, 00067 FT_Long size, 00068 FT_Error *p_error ) 00069 { 00070 FT_Error error = FT_Err_Ok; 00071 FT_Pointer block = NULL; 00072 00073 00074 if ( size > 0 ) 00075 { 00076 block = memory->alloc( memory, size ); 00077 if ( block == NULL ) 00078 error = FT_Err_Out_Of_Memory; 00079 } 00080 else if ( size < 0 ) 00081 { 00082 /* may help catch/prevent security issues */ 00083 error = FT_Err_Invalid_Argument; 00084 } 00085 00086 *p_error = error; 00087 return block; 00088 } 00089 00090 00091 FT_BASE_DEF( FT_Pointer ) 00092 ft_mem_realloc( FT_Memory memory, 00093 FT_Long item_size, 00094 FT_Long cur_count, 00095 FT_Long new_count, 00096 void* block, 00097 FT_Error *p_error ) 00098 { 00099 FT_Error error = FT_Err_Ok; 00100 00101 block = ft_mem_qrealloc( memory, item_size, 00102 cur_count, new_count, block, &error ); 00103 if ( !error && new_count > cur_count ) 00104 FT_MEM_ZERO( (char*)block + cur_count * item_size, 00105 ( new_count - cur_count ) * item_size ); 00106 00107 *p_error = error; 00108 return block; 00109 } 00110 00111 00112 FT_BASE_DEF( FT_Pointer ) 00113 ft_mem_qrealloc( FT_Memory memory, 00114 FT_Long item_size, 00115 FT_Long cur_count, 00116 FT_Long new_count, 00117 void* block, 00118 FT_Error *p_error ) 00119 { 00120 FT_Error error = FT_Err_Ok; 00121 00122 00123 /* Note that we now accept `item_size == 0' as a valid parameter, in 00124 * order to cover very weird cases where an ALLOC_MULT macro would be 00125 * called. 00126 */ 00127 if ( cur_count < 0 || new_count < 0 || item_size < 0 ) 00128 { 00129 /* may help catch/prevent nasty security issues */ 00130 error = FT_Err_Invalid_Argument; 00131 } 00132 else if ( new_count == 0 || item_size == 0 ) 00133 { 00134 ft_mem_free( memory, block ); 00135 block = NULL; 00136 } 00137 else if ( new_count > FT_INT_MAX/item_size ) 00138 { 00139 error = FT_Err_Array_Too_Large; 00140 } 00141 else if ( cur_count == 0 ) 00142 { 00143 FT_ASSERT( block == NULL ); 00144 00145 block = ft_mem_alloc( memory, new_count*item_size, &error ); 00146 } 00147 else 00148 { 00149 FT_Pointer block2; 00150 FT_Long cur_size = cur_count*item_size; 00151 FT_Long new_size = new_count*item_size; 00152 00153 00154 block2 = memory->realloc( memory, cur_size, new_size, block ); 00155 if ( block2 == NULL ) 00156 error = FT_Err_Out_Of_Memory; 00157 else 00158 block = block2; 00159 } 00160 00161 *p_error = error; 00162 return block; 00163 } 00164 00165 00166 FT_BASE_DEF( void ) 00167 ft_mem_free( FT_Memory memory, 00168 const void *P ) 00169 { 00170 if ( P ) 00171 memory->free( memory, (void*)P ); 00172 } 00173 00174 00175 FT_BASE_DEF( FT_Pointer ) 00176 ft_mem_dup( FT_Memory memory, 00177 const void* address, 00178 FT_ULong size, 00179 FT_Error *p_error ) 00180 { 00181 FT_Error error; 00182 FT_Pointer p = ft_mem_qalloc( memory, size, &error ); 00183 00184 00185 if ( !error && address ) 00186 ft_memcpy( p, address, size ); 00187 00188 *p_error = error; 00189 return p; 00190 } 00191 00192 00193 FT_BASE_DEF( FT_Pointer ) 00194 ft_mem_strdup( FT_Memory memory, 00195 const char* str, 00196 FT_Error *p_error ) 00197 { 00198 FT_ULong len = str ? (FT_ULong)ft_strlen( str ) + 1 00199 : 0; 00200 00201 00202 return ft_mem_dup( memory, str, len, p_error ); 00203 } 00204 00205 00206 FT_BASE_DEF( FT_Int ) 00207 ft_mem_strcpyn( char* dst, 00208 const char* src, 00209 FT_ULong size ) 00210 { 00211 while ( size > 1 && *src != 0 ) 00212 { 00213 *dst++ = *src++; 00214 size--; 00215 } 00216 00217 *dst = 0; /* always zero-terminate */ 00218 00219 return *src != 0; 00220 } 00221 00222 00223 /*************************************************************************/ 00224 /*************************************************************************/ 00225 /*************************************************************************/ 00226 /***** *****/ 00227 /***** *****/ 00228 /***** D O U B L Y L I N K E D L I S T S *****/ 00229 /***** *****/ 00230 /***** *****/ 00231 /*************************************************************************/ 00232 /*************************************************************************/ 00233 /*************************************************************************/ 00234 00235 #undef FT_COMPONENT 00236 #define FT_COMPONENT trace_list 00237 00238 /* documentation is in ftlist.h */ 00239 00240 FT_EXPORT_DEF( FT_ListNode ) 00241 FT_List_Find( FT_List list, 00242 void* data ) 00243 { 00244 FT_ListNode cur; 00245 00246 00247 cur = list->head; 00248 while ( cur ) 00249 { 00250 if ( cur->data == data ) 00251 return cur; 00252 00253 cur = cur->next; 00254 } 00255 00256 return (FT_ListNode)0; 00257 } 00258 00259 00260 /* documentation is in ftlist.h */ 00261 00262 FT_EXPORT_DEF( void ) 00263 FT_List_Add( FT_List list, 00264 FT_ListNode node ) 00265 { 00266 FT_ListNode before = list->tail; 00267 00268 00269 node->next = 0; 00270 node->prev = before; 00271 00272 if ( before ) 00273 before->next = node; 00274 else 00275 list->head = node; 00276 00277 list->tail = node; 00278 } 00279 00280 00281 /* documentation is in ftlist.h */ 00282 00283 FT_EXPORT_DEF( void ) 00284 FT_List_Insert( FT_List list, 00285 FT_ListNode node ) 00286 { 00287 FT_ListNode after = list->head; 00288 00289 00290 node->next = after; 00291 node->prev = 0; 00292 00293 if ( !after ) 00294 list->tail = node; 00295 else 00296 after->prev = node; 00297 00298 list->head = node; 00299 } 00300 00301 00302 /* documentation is in ftlist.h */ 00303 00304 FT_EXPORT_DEF( void ) 00305 FT_List_Remove( FT_List list, 00306 FT_ListNode node ) 00307 { 00308 FT_ListNode before, after; 00309 00310 00311 before = node->prev; 00312 after = node->next; 00313 00314 if ( before ) 00315 before->next = after; 00316 else 00317 list->head = after; 00318 00319 if ( after ) 00320 after->prev = before; 00321 else 00322 list->tail = before; 00323 } 00324 00325 00326 /* documentation is in ftlist.h */ 00327 00328 FT_EXPORT_DEF( void ) 00329 FT_List_Up( FT_List list, 00330 FT_ListNode node ) 00331 { 00332 FT_ListNode before, after; 00333 00334 00335 before = node->prev; 00336 after = node->next; 00337 00338 /* check whether we are already on top of the list */ 00339 if ( !before ) 00340 return; 00341 00342 before->next = after; 00343 00344 if ( after ) 00345 after->prev = before; 00346 else 00347 list->tail = before; 00348 00349 node->prev = 0; 00350 node->next = list->head; 00351 list->head->prev = node; 00352 list->head = node; 00353 } 00354 00355 00356 /* documentation is in ftlist.h */ 00357 00358 FT_EXPORT_DEF( FT_Error ) 00359 FT_List_Iterate( FT_List list, 00360 FT_List_Iterator iterator, 00361 void* user ) 00362 { 00363 FT_ListNode cur = list->head; 00364 FT_Error error = FT_Err_Ok; 00365 00366 00367 while ( cur ) 00368 { 00369 FT_ListNode next = cur->next; 00370 00371 00372 error = iterator( cur, user ); 00373 if ( error ) 00374 break; 00375 00376 cur = next; 00377 } 00378 00379 return error; 00380 } 00381 00382 00383 /* documentation is in ftlist.h */ 00384 00385 FT_EXPORT_DEF( void ) 00386 FT_List_Finalize( FT_List list, 00387 FT_List_Destructor destroy, 00388 FT_Memory memory, 00389 void* user ) 00390 { 00391 FT_ListNode cur; 00392 00393 00394 cur = list->head; 00395 while ( cur ) 00396 { 00397 FT_ListNode next = cur->next; 00398 void* data = cur->data; 00399 00400 00401 if ( destroy ) 00402 destroy( memory, data, user ); 00403 00404 FT_FREE( cur ); 00405 cur = next; 00406 } 00407 00408 list->head = 0; 00409 list->tail = 0; 00410 } 00411 00412 00413 FT_BASE_DEF( FT_UInt32 ) 00414 ft_highpow2( FT_UInt32 value ) 00415 { 00416 FT_UInt32 value2; 00417 00418 00419 /* 00420 * We simply clear the lowest bit in each iteration. When 00421 * we reach 0, we know that the previous value was our result. 00422 */ 00423 for ( ;; ) 00424 { 00425 value2 = value & (value - 1); /* clear lowest bit */ 00426 if ( value2 == 0 ) 00427 break; 00428 00429 value = value2; 00430 } 00431 return value; 00432 } 00433 00434 00435 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS 00436 00437 FT_BASE_DEF( FT_Error ) 00438 FT_Alloc( FT_Memory memory, 00439 FT_Long size, 00440 void* *P ) 00441 { 00442 FT_Error error; 00443 00444 00445 (void)FT_ALLOC( *P, size ); 00446 return error; 00447 } 00448 00449 00450 FT_BASE_DEF( FT_Error ) 00451 FT_QAlloc( FT_Memory memory, 00452 FT_Long size, 00453 void* *p ) 00454 { 00455 FT_Error error; 00456 00457 00458 (void)FT_QALLOC( *p, size ); 00459 return error; 00460 } 00461 00462 00463 FT_BASE_DEF( FT_Error ) 00464 FT_Realloc( FT_Memory memory, 00465 FT_Long current, 00466 FT_Long size, 00467 void* *P ) 00468 { 00469 FT_Error error; 00470 00471 00472 (void)FT_REALLOC( *P, current, size ); 00473 return error; 00474 } 00475 00476 00477 FT_BASE_DEF( FT_Error ) 00478 FT_QRealloc( FT_Memory memory, 00479 FT_Long current, 00480 FT_Long size, 00481 void* *p ) 00482 { 00483 FT_Error error; 00484 00485 00486 (void)FT_QREALLOC( *p, current, size ); 00487 return error; 00488 } 00489 00490 00491 FT_BASE_DEF( void ) 00492 FT_Free( FT_Memory memory, 00493 void* *P ) 00494 { 00495 if ( *P ) 00496 FT_MEM_FREE( *P ); 00497 } 00498 00499 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ 00500 00501 /* END */ Generated on Sun May 27 2012 04:33:47 for ReactOS by
1.7.6.1
|