/src/freetype/src/cache/ftcmru.c
https://bitbucket.org/cabalistic/ogredeps/ · C · 357 lines · 252 code · 88 blank · 17 comment · 52 complexity · e55c0ad255d1a918d2dd91dae9deab1c MD5 · raw file
- /***************************************************************************/
- /* */
- /* ftcmru.c */
- /* */
- /* FreeType MRU support (body). */
- /* */
- /* Copyright 2003, 2004, 2006, 2009 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 */