ftutil.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 Tue Jul 5 14:13:43 2011 for ROOT_528-00b_version by  doxygen 1.5.1