2003-12-19 22:23:58 +01:00
|
|
|
#include <ft2build.h>
|
|
|
|
#include FT_CACHE_H
|
|
|
|
#include FT_CACHE_INTERNAL_MRU_H
|
|
|
|
#include FT_INTERNAL_OBJECTS_H
|
|
|
|
#include FT_INTERNAL_DEBUG_H
|
|
|
|
|
|
|
|
#include "ftcerror.h"
|
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
|
|
|
|
FT_EXPORT_DEF( void )
|
|
|
|
FTC_MruNode_Prepend( FTC_MruNode *plist,
|
|
|
|
FTC_MruNode node )
|
|
|
|
{
|
|
|
|
FTC_MruNode first = *plist;
|
|
|
|
|
|
|
|
if ( first )
|
|
|
|
{
|
|
|
|
FTC_MruNode last = first->prev;
|
|
|
|
|
|
|
|
last->next = node;
|
|
|
|
first->prev = node;
|
|
|
|
node->prev = last;
|
|
|
|
node->next = first;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
node->next = node;
|
|
|
|
node->prev = node;
|
|
|
|
}
|
|
|
|
*plist = node;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FT_EXPORT_DEF( void )
|
|
|
|
FTC_MruNode_Up( FTC_MruNode *plist,
|
|
|
|
FTC_MruNode node )
|
|
|
|
{
|
|
|
|
FTC_MruNode first = *plist;
|
|
|
|
|
|
|
|
FT_ASSERT( first != NULL );
|
|
|
|
|
|
|
|
if ( node != first )
|
|
|
|
{
|
|
|
|
FTC_MruNode prev = node->prev;
|
|
|
|
FTC_MruNode next = node->next;
|
|
|
|
FTC_MruNode last;
|
|
|
|
|
|
|
|
prev->next = next;
|
|
|
|
next->prev = prev;
|
|
|
|
|
|
|
|
last = first->prev;
|
|
|
|
|
|
|
|
first->prev = node;
|
|
|
|
last->next = node;
|
|
|
|
|
|
|
|
node->prev = last;
|
|
|
|
node->next = first;
|
|
|
|
|
|
|
|
*plist = node;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FT_EXPORT( void )
|
|
|
|
FTC_MruNode_Remove( FTC_MruNode *plist,
|
|
|
|
FTC_MruNode node )
|
|
|
|
{
|
|
|
|
FTC_MruNode first = *plist;
|
|
|
|
FTC_MruNode prev, next;
|
|
|
|
|
|
|
|
FT_ASSERT( first != NULL );
|
|
|
|
|
|
|
|
next = node->next;
|
|
|
|
prev = node->prev;
|
|
|
|
|
|
|
|
if ( node == next )
|
|
|
|
{
|
|
|
|
FT_ASSERT( node == prev );
|
|
|
|
FT_ASSERT( node == first );
|
|
|
|
|
|
|
|
*plist = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prev->next = next;
|
|
|
|
next->prev = prev;
|
|
|
|
|
|
|
|
if ( node == first )
|
|
|
|
*plist = next;
|
|
|
|
}
|
|
|
|
node->prev = NULL;
|
|
|
|
node->next = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2003-12-19 22:23:58 +01:00
|
|
|
FT_EXPORT_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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
|
|
|
|
|
|
|
|
FT_EXPORT( void )
|
|
|
|
FTC_MruList_Reset( FTC_MruList list )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
FT_Memory memory = list->memory;
|
|
|
|
FTC_MruNode first = list->nodes;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
if ( first )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruNode node = first;
|
|
|
|
FTC_MruNode next;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
do
|
|
|
|
{
|
|
|
|
next = node->next;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
if ( list->clazz.node_done )
|
|
|
|
list->clazz.node_done( node, list->data );
|
|
|
|
|
|
|
|
FT_FREE( node );
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
node = next;
|
|
|
|
}
|
|
|
|
while ( node != first );
|
2003-12-19 22:23:58 +01:00
|
|
|
}
|
2003-12-21 02:41:32 +01:00
|
|
|
list->nodes = NULL;
|
|
|
|
list->num_nodes = 0;
|
2003-12-19 22:23:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FT_EXPORT( void )
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruList_Done( FTC_MruList list )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruList_Reset( list );
|
2003-12-19 22:23:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
FT_EXPORT_DEF( void )
|
|
|
|
FTC_MruList_Up( FTC_MruList list,
|
|
|
|
FTC_MruNode node )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruNode_Up( &list->nodes, node );
|
2003-12-19 22:23:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
FT_EXPORT_DEF( FTC_MruNode )
|
|
|
|
FTC_MruList_Lookup( FTC_MruList list,
|
|
|
|
FT_Pointer key )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
|
|
|
FTC_MruNode_CompareFunc compare = list->clazz.node_compare;
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruNode node, first;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
first = list->nodes;
|
|
|
|
node = NULL;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
if ( first )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
node = first;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( compare( node, key ) )
|
|
|
|
goto Exit;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
node = node->next;
|
|
|
|
|
|
|
|
} while ( node != first );
|
|
|
|
|
|
|
|
node = NULL;
|
2003-12-19 22:23:58 +01:00
|
|
|
}
|
2003-12-21 02:41:32 +01:00
|
|
|
Exit:
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_EXPORT_DEF( FT_Error )
|
|
|
|
FTC_MruList_New( FTC_MruList list,
|
|
|
|
FT_Pointer key,
|
|
|
|
FTC_MruNode *anode )
|
|
|
|
{
|
|
|
|
FT_Memory memory = list->memory;
|
|
|
|
FT_Error error;
|
|
|
|
FTC_MruNode node;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
|
|
|
if ( list->max_nodes > 0 && list->num_nodes >= list->max_nodes )
|
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
FT_ASSERT( list->nodes != NULL );
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
node = list->nodes->prev; /* last node */
|
|
|
|
|
|
|
|
if ( list->clazz.node_reset )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruNode_Up( &list->nodes, node );
|
|
|
|
|
|
|
|
error = list->clazz.node_reset( node, key, list->data );
|
|
|
|
if ( !error )
|
|
|
|
goto Exit;
|
|
|
|
}
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruNode_Remove( &list->nodes, node );
|
|
|
|
list->num_nodes--;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
if ( list->clazz.node_done )
|
2003-12-19 22:23:58 +01:00
|
|
|
list->clazz.node_done( node, list->data );
|
|
|
|
}
|
2003-12-21 02:41:32 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( FT_ALLOC( node, list->clazz.node_size ) )
|
|
|
|
goto Exit;
|
|
|
|
}
|
2003-12-19 22:23:58 +01:00
|
|
|
error = list->clazz.node_init( node, key, list->data );
|
2003-12-21 02:41:32 +01:00
|
|
|
if ( !error )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruNode_Prepend( &list->nodes, node );
|
|
|
|
list->num_nodes++;
|
2003-12-19 22:23:58 +01:00
|
|
|
goto Exit;
|
|
|
|
}
|
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
if ( list->clazz.node_done )
|
|
|
|
list->clazz.node_done( node, list->data );
|
|
|
|
|
|
|
|
FT_FREE( node );
|
2003-12-19 22:23:58 +01:00
|
|
|
|
|
|
|
Exit:
|
|
|
|
*anode = node;
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
|
|
|
|
FT_EXPORT_DEF( FT_Error )
|
|
|
|
FTC_MruList_Get( FTC_MruList list,
|
|
|
|
FT_Pointer key,
|
|
|
|
FTC_MruNode *anode )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
FT_Error error = 0;
|
|
|
|
FTC_MruNode node;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
node = FTC_MruList_Lookup( list, key );
|
|
|
|
if ( node == NULL )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
error = FTC_MruList_New( list, key, &node );
|
|
|
|
if ( error )
|
|
|
|
node = NULL;
|
|
|
|
}
|
|
|
|
*anode = node;
|
|
|
|
return error;
|
|
|
|
}
|
2003-12-19 22:23:58 +01:00
|
|
|
|
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
FT_EXPORT_DEF( void )
|
|
|
|
FTC_MruList_Remove( FTC_MruList list,
|
|
|
|
FTC_MruNode node )
|
|
|
|
{
|
|
|
|
FT_Memory memory = list->memory;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
FT_ASSERT( list->nodes != NULL && list->num_nodes > 0 );
|
|
|
|
|
|
|
|
FTC_MruNode_Remove( &list->nodes, node );
|
2003-12-19 22:23:58 +01:00
|
|
|
list->num_nodes--;
|
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
if ( list->clazz.node_done )
|
|
|
|
list->clazz.node_done( node, list->data );
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
FT_FREE( node );
|
2003-12-19 22:23:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FT_EXPORT_DEF( void )
|
|
|
|
FTC_MruList_RemoveSelection( FTC_MruList list,
|
|
|
|
FTC_MruNode_CompareFunc select,
|
|
|
|
FT_Pointer key )
|
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruNode first = list->nodes;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
while ( first && select( first, key ) )
|
2003-12-19 22:23:58 +01:00
|
|
|
{
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruList_Remove( list, first );
|
|
|
|
first = list->nodes;
|
|
|
|
}
|
2003-12-19 22:23:58 +01:00
|
|
|
|
2003-12-21 02:41:32 +01:00
|
|
|
if ( first )
|
|
|
|
{
|
|
|
|
FTC_MruNode node = first->next;
|
|
|
|
FTC_MruNode next;
|
|
|
|
|
|
|
|
while ( node != first )
|
|
|
|
{
|
|
|
|
next = node->next;
|
2003-12-19 22:23:58 +01:00
|
|
|
|
|
|
|
if ( select( node, key ) )
|
2003-12-21 02:41:32 +01:00
|
|
|
FTC_MruList_Remove( list, node );
|
|
|
|
|
|
|
|
node = next;
|
2003-12-19 22:23:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* END */
|
|
|
|
|