ftcmru.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ftcmru.c                                                               */
00004 /*                                                                         */
00005 /*    FreeType MRU support (body).                                         */
00006 /*                                                                         */
00007 /*  Copyright 2003, 2004, 2006, 2009 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_CACHE_H
00021 #include "ftcmru.h"
00022 #include FT_INTERNAL_OBJECTS_H
00023 #include FT_INTERNAL_DEBUG_H
00024 
00025 #include "ftcerror.h"
00026 
00027 
00028   FT_LOCAL_DEF( void )
00029   FTC_MruNode_Prepend( FTC_MruNode  *plist,
00030                        FTC_MruNode   node )
00031   {
00032     FTC_MruNode  first = *plist;
00033 
00034 
00035     if ( first )
00036     {
00037       FTC_MruNode  last = first->prev;
00038 
00039 
00040 #ifdef FT_DEBUG_ERROR
00041       {
00042         FTC_MruNode  cnode = first;
00043 
00044 
00045         do
00046         {
00047           if ( cnode == node )
00048           {
00049             fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" );
00050             exit( 2 );
00051           }
00052           cnode = cnode->next;
00053 
00054         } while ( cnode != first );
00055       }
00056 #endif
00057 
00058       first->prev = node;
00059       last->next  = node;
00060       node->next  = first;
00061       node->prev  = last;
00062     }
00063     else
00064     {
00065       node->next = node;
00066       node->prev = node;
00067     }
00068     *plist = node;
00069   }
00070 
00071 
00072   FT_LOCAL_DEF( void )
00073   FTC_MruNode_Up( FTC_MruNode  *plist,
00074                   FTC_MruNode   node )
00075   {
00076     FTC_MruNode  first = *plist;
00077 
00078 
00079     FT_ASSERT( first != NULL );
00080 
00081     if ( first != node )
00082     {
00083       FTC_MruNode  prev, next, last;
00084 
00085 
00086 #ifdef FT_DEBUG_ERROR
00087       {
00088         FTC_MruNode  cnode = first;
00089         do
00090         {
00091           if ( cnode == node )
00092             goto Ok;
00093           cnode = cnode->next;
00094 
00095         } while ( cnode != first );
00096 
00097         fprintf( stderr, "FTC_MruNode_Up: invalid action\n" );
00098         exit( 2 );
00099       Ok:
00100       }
00101 #endif
00102       prev = node->prev;
00103       next = node->next;
00104 
00105       prev->next = next;
00106       next->prev = prev;
00107 
00108       last = first->prev;
00109 
00110       last->next  = node;
00111       first->prev = node;
00112 
00113       node->next = first;
00114       node->prev = last;
00115 
00116       *plist = node;
00117     }
00118   }
00119 
00120 
00121   FT_LOCAL_DEF( void )
00122   FTC_MruNode_Remove( FTC_MruNode  *plist,
00123                       FTC_MruNode   node )
00124   {
00125     FTC_MruNode  first = *plist;
00126     FTC_MruNode  prev, next;
00127 
00128 
00129     FT_ASSERT( first != NULL );
00130 
00131 #ifdef FT_DEBUG_ERROR
00132       {
00133         FTC_MruNode  cnode = first;
00134 
00135 
00136         do
00137         {
00138           if ( cnode == node )
00139             goto Ok;
00140           cnode = cnode->next;
00141 
00142         } while ( cnode != first );
00143 
00144         fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" );
00145         exit( 2 );
00146       Ok:
00147       }
00148 #endif
00149 
00150     prev = node->prev;
00151     next = node->next;
00152 
00153     prev->next = next;
00154     next->prev = prev;
00155 
00156     if ( node == next )
00157     {
00158       FT_ASSERT( first == node );
00159       FT_ASSERT( prev  == node );
00160 
00161       *plist = NULL;
00162     }
00163     else if ( node == first )
00164         *plist = next;
00165   }
00166 
00167 
00168   FT_LOCAL_DEF( void )
00169   FTC_MruList_Init( FTC_MruList       list,
00170                     FTC_MruListClass  clazz,
00171                     FT_UInt           max_nodes,
00172                     FT_Pointer        data,
00173                     FT_Memory         memory )
00174   {
00175     list->num_nodes = 0;
00176     list->max_nodes = max_nodes;
00177     list->nodes     = NULL;
00178     list->clazz     = *clazz;
00179     list->data      = data;
00180     list->memory    = memory;
00181   }
00182 
00183 
00184   FT_LOCAL_DEF( void )
00185   FTC_MruList_Reset( FTC_MruList  list )
00186   {
00187     while ( list->nodes )
00188       FTC_MruList_Remove( list, list->nodes );
00189 
00190     FT_ASSERT( list->num_nodes == 0 );
00191   }
00192 
00193 
00194   FT_LOCAL_DEF( void )
00195   FTC_MruList_Done( FTC_MruList  list )
00196   {
00197     FTC_MruList_Reset( list );
00198   }
00199 
00200 
00201 #ifndef FTC_INLINE
00202   FT_LOCAL_DEF( FTC_MruNode )
00203   FTC_MruList_Find( FTC_MruList  list,
00204                     FT_Pointer   key )
00205   {
00206     FTC_MruNode_CompareFunc  compare = list->clazz.node_compare;
00207     FTC_MruNode              first, node;
00208 
00209 
00210     first = list->nodes;
00211     node  = NULL;
00212 
00213     if ( first )
00214     {
00215       node = first;
00216       do
00217       {
00218         if ( compare( node, key ) )
00219         {
00220           if ( node != first )
00221             FTC_MruNode_Up( &list->nodes, node );
00222 
00223           return node;
00224         }
00225 
00226         node = node->next;
00227 
00228       } while ( node != first);
00229     }
00230 
00231     return NULL;
00232   }
00233 #endif
00234 
00235   FT_LOCAL_DEF( FT_Error )
00236   FTC_MruList_New( FTC_MruList   list,
00237                    FT_Pointer    key,
00238                    FTC_MruNode  *anode )
00239   {
00240     FT_Error     error;
00241     FTC_MruNode  node;
00242     FT_Memory    memory = list->memory;
00243 
00244 
00245     if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )
00246     {
00247       node = list->nodes->prev;
00248 
00249       FT_ASSERT( node );
00250 
00251       if ( list->clazz.node_reset )
00252       {
00253         FTC_MruNode_Up( &list->nodes, node );
00254 
00255         error = list->clazz.node_reset( node, key, list->data );
00256         if ( !error )
00257           goto Exit;
00258       }
00259 
00260       FTC_MruNode_Remove( &list->nodes, node );
00261       list->num_nodes--;
00262 
00263       if ( list->clazz.node_done )
00264         list->clazz.node_done( node, list->data );
00265     }
00266     else if ( FT_ALLOC( node, list->clazz.node_size ) )
00267         goto Exit;
00268 
00269     error = list->clazz.node_init( node, key, list->data );
00270     if ( error )
00271       goto Fail;
00272 
00273       FTC_MruNode_Prepend( &list->nodes, node );
00274       list->num_nodes++;
00275 
00276   Exit:
00277     *anode = node;
00278     return error;
00279 
00280   Fail:
00281     if ( list->clazz.node_done )
00282       list->clazz.node_done( node, list->data );
00283 
00284     FT_FREE( node );
00285     goto Exit;
00286   }
00287 
00288 
00289 #ifndef FTC_INLINE
00290   FT_LOCAL_DEF( FT_Error )
00291   FTC_MruList_Lookup( FTC_MruList   list,
00292                       FT_Pointer    key,
00293                       FTC_MruNode  *anode )
00294   {
00295     FTC_MruNode  node;
00296 
00297 
00298     node = FTC_MruList_Find( list, key );
00299     if ( node == NULL )
00300       return FTC_MruList_New( list, key, anode );
00301 
00302     *anode = node;
00303     return 0;
00304   }
00305 #endif /* FTC_INLINE */
00306 
00307   FT_LOCAL_DEF( void )
00308   FTC_MruList_Remove( FTC_MruList  list,
00309                       FTC_MruNode  node )
00310   {
00311     FTC_MruNode_Remove( &list->nodes, node );
00312     list->num_nodes--;
00313 
00314     {
00315       FT_Memory  memory = list->memory;
00316 
00317 
00318       if ( list->clazz.node_done )
00319        list->clazz.node_done( node, list->data );
00320 
00321       FT_FREE( node );
00322     }
00323   }
00324 
00325 
00326   FT_LOCAL_DEF( void )
00327   FTC_MruList_RemoveSelection( FTC_MruList              list,
00328                                FTC_MruNode_CompareFunc  selection,
00329                                FT_Pointer               key )
00330   {
00331     FTC_MruNode  first, node, next;
00332 
00333 
00334     first = list->nodes;
00335     while ( first && ( selection == NULL || selection( first, key ) ) )
00336     {
00337       FTC_MruList_Remove( list, first );
00338       first = list->nodes;
00339     }
00340 
00341     if ( first )
00342     {
00343       node = first->next;
00344       while ( node != first )
00345       {
00346         next = node->next;
00347 
00348         if ( selection( node, key ) )
00349           FTC_MruList_Remove( list, node );
00350 
00351         node = next;
00352       }
00353     }
00354   }
00355 
00356 
00357 /* END */

Generated on Tue Jul 5 14:13:45 2011 for ROOT_528-00b_version by  doxygen 1.5.1