Edit

kc3-lang/freetype/src/cache/ftcmru.c

Branch :

  • Show log

    Commit

  • Author : Werner Lemberg
    Date : 2016-01-13 11:54:10
    Hash : 9adeab64
    Message : Update copyright year.

  • src/cache/ftcmru.c
  • /***************************************************************************/
    /*                                                                         */
    /*  ftcmru.c                                                               */
    /*                                                                         */
    /*    FreeType MRU support (body).                                         */
    /*                                                                         */
    /*  Copyright 2003-2016 by                                                 */
    /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    /*                                                                         */
    /*  This file is part of the FreeType project, and may only be used,       */
    /*  modified, and distributed under the terms of the FreeType project      */
    /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
    /*  this file you indicate that you have read the license and              */
    /*  understand and accept it fully.                                        */
    /*                                                                         */
    /***************************************************************************/
    
    
    #include <ft2build.h>
    #include FT_CACHE_H
    #include "ftcmru.h"
    #include FT_INTERNAL_OBJECTS_H
    #include FT_INTERNAL_DEBUG_H
    
    #include "ftcerror.h"
    
    
      FT_LOCAL_DEF( void )
      FTC_MruNode_Prepend( FTC_MruNode  *plist,
                           FTC_MruNode   node )
      {
        FTC_MruNode  first = *plist;
    
    
        if ( first )
        {
          FTC_MruNode  last = first->prev;
    
    
    #ifdef FT_DEBUG_ERROR
          {
            FTC_MruNode  cnode = first;
    
    
            do
            {
              if ( cnode == node )
              {
                fprintf( stderr, "FTC_MruNode_Prepend: invalid action\n" );
                exit( 2 );
              }
              cnode = cnode->next;
    
            } while ( cnode != first );
          }
    #endif
    
          first->prev = node;
          last->next  = node;
          node->next  = first;
          node->prev  = last;
        }
        else
        {
          node->next = node;
          node->prev = node;
        }
        *plist = node;
      }
    
    
      FT_LOCAL_DEF( void )
      FTC_MruNode_Up( FTC_MruNode  *plist,
                      FTC_MruNode   node )
      {
        FTC_MruNode  first = *plist;
    
    
        FT_ASSERT( first != NULL );
    
        if ( first != node )
        {
          FTC_MruNode  prev, next, last;
    
    
    #ifdef FT_DEBUG_ERROR
          {
            FTC_MruNode  cnode = first;
            do
            {
              if ( cnode == node )
                goto Ok;
              cnode = cnode->next;
    
            } while ( cnode != first );
    
            fprintf( stderr, "FTC_MruNode_Up: invalid action\n" );
            exit( 2 );
          Ok:
          }
    #endif
          prev = node->prev;
          next = node->next;
    
          prev->next = next;
          next->prev = prev;
    
          last = first->prev;
    
          last->next  = node;
          first->prev = node;
    
          node->next = first;
          node->prev = last;
    
          *plist = node;
        }
      }
    
    
      FT_LOCAL_DEF( void )
      FTC_MruNode_Remove( FTC_MruNode  *plist,
                          FTC_MruNode   node )
      {
        FTC_MruNode  first = *plist;
        FTC_MruNode  prev, next;
    
    
        FT_ASSERT( first != NULL );
    
    #ifdef FT_DEBUG_ERROR
          {
            FTC_MruNode  cnode = first;
    
    
            do
            {
              if ( cnode == node )
                goto Ok;
              cnode = cnode->next;
    
            } while ( cnode != first );
    
            fprintf( stderr, "FTC_MruNode_Remove: invalid action\n" );
            exit( 2 );
          Ok:
          }
    #endif
    
        prev = node->prev;
        next = node->next;
    
        prev->next = next;
        next->prev = prev;
    
        if ( node == next )
        {
          FT_ASSERT( first == node );
          FT_ASSERT( prev  == node );
    
          *plist = NULL;
        }
        else if ( node == first )
          *plist = next;
      }
    
    
      FT_LOCAL_DEF( void )
      FTC_MruList_Init( FTC_MruList       list,
                        FTC_MruListClass  clazz,
                        FT_UInt           max_nodes,
                        FT_Pointer        data,
                        FT_Memory         memory )
      {
        list->num_nodes = 0;
        list->max_nodes = max_nodes;
        list->nodes     = NULL;
        list->clazz     = *clazz;
        list->data      = data;
        list->memory    = memory;
      }
    
    
      FT_LOCAL_DEF( void )
      FTC_MruList_Reset( FTC_MruList  list )
      {
        while ( list->nodes )
          FTC_MruList_Remove( list, list->nodes );
    
        FT_ASSERT( list->num_nodes == 0 );
      }
    
    
      FT_LOCAL_DEF( void )
      FTC_MruList_Done( FTC_MruList  list )
      {
        FTC_MruList_Reset( list );
      }
    
    
    #ifndef FTC_INLINE
      FT_LOCAL_DEF( FTC_MruNode )
      FTC_MruList_Find( FTC_MruList  list,
                        FT_Pointer   key )
      {
        FTC_MruNode_CompareFunc  compare = list->clazz.node_compare;
        FTC_MruNode              first, node;
    
    
        first = list->nodes;
        node  = NULL;
    
        if ( first )
        {
          node = first;
          do
          {
            if ( compare( node, key ) )
            {
              if ( node != first )
                FTC_MruNode_Up( &list->nodes, node );
    
              return node;
            }
    
            node = node->next;
    
          } while ( node != first);
        }
    
        return NULL;
      }
    #endif
    
      FT_LOCAL_DEF( FT_Error )
      FTC_MruList_New( FTC_MruList   list,
                       FT_Pointer    key,
                       FTC_MruNode  *anode )
      {
        FT_Error     error;
        FTC_MruNode  node = NULL;
        FT_Memory    memory = list->memory;
    
    
        if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )
        {
          node = list->nodes->prev;
    
          FT_ASSERT( node );
    
          if ( list->clazz.node_reset )
          {
            FTC_MruNode_Up( &list->nodes, node );
    
            error = list->clazz.node_reset( node, key, list->data );
            if ( !error )
              goto Exit;
          }
    
          FTC_MruNode_Remove( &list->nodes, node );
          list->num_nodes--;
    
          if ( list->clazz.node_done )
            list->clazz.node_done( node, list->data );
        }
        else if ( FT_ALLOC( node, list->clazz.node_size ) )
          goto Exit;
    
        error = list->clazz.node_init( node, key, list->data );
        if ( error )
          goto Fail;
    
        FTC_MruNode_Prepend( &list->nodes, node );
        list->num_nodes++;
    
      Exit:
        *anode = node;
        return error;
    
      Fail:
        if ( list->clazz.node_done )
          list->clazz.node_done( node, list->data );
    
        FT_FREE( node );
        goto Exit;
      }
    
    
    #ifndef FTC_INLINE
      FT_LOCAL_DEF( FT_Error )
      FTC_MruList_Lookup( FTC_MruList   list,
                          FT_Pointer    key,
                          FTC_MruNode  *anode )
      {
        FTC_MruNode  node;
    
    
        node = FTC_MruList_Find( list, key );
        if ( node == NULL )
          return FTC_MruList_New( list, key, anode );
    
        *anode = node;
        return 0;
      }
    #endif /* FTC_INLINE */
    
      FT_LOCAL_DEF( void )
      FTC_MruList_Remove( FTC_MruList  list,
                          FTC_MruNode  node )
      {
        FTC_MruNode_Remove( &list->nodes, node );
        list->num_nodes--;
    
        {
          FT_Memory  memory = list->memory;
    
    
          if ( list->clazz.node_done )
            list->clazz.node_done( node, list->data );
    
          FT_FREE( node );
        }
      }
    
    
      FT_LOCAL_DEF( void )
      FTC_MruList_RemoveSelection( FTC_MruList              list,
                                   FTC_MruNode_CompareFunc  selection,
                                   FT_Pointer               key )
      {
        FTC_MruNode  first, node, next;
    
    
        first = list->nodes;
        while ( first && ( selection == NULL || selection( first, key ) ) )
        {
          FTC_MruList_Remove( list, first );
          first = list->nodes;
        }
    
        if ( first )
        {
          node = first->next;
          while ( node != first )
          {
            next = node->next;
    
            if ( selection( node, key ) )
              FTC_MruList_Remove( list, node );
    
            node = next;
          }
        }
      }
    
    
    /* END */