205 lines
4.1 KiB
C
205 lines
4.1 KiB
C
|
#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"
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
static void
|
||
|
ftc_mrulist_free_nodes( FTC_MruList list,
|
||
|
FTC_MruNode *plist )
|
||
|
{
|
||
|
FT_Memory memory = list->memory;
|
||
|
|
||
|
while ( *plist )
|
||
|
{
|
||
|
FTC_MruNode node = *plist;
|
||
|
|
||
|
*plist = node->next;
|
||
|
|
||
|
if ( list->clazz.node_done )
|
||
|
list->clazz.node_done( node, list->data );
|
||
|
|
||
|
FT_FREE( node );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
FT_EXPORT( void )
|
||
|
FTC_MruList_Reset( FTC_MruList list )
|
||
|
{
|
||
|
ftc_mrulist_free_nodes( list, &list->nodes );
|
||
|
list->num_nodes = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
FT_EXPORT( void )
|
||
|
FTC_MruList_Done( FTC_MruList list )
|
||
|
{
|
||
|
FTC_MruList_Reset( list );
|
||
|
}
|
||
|
|
||
|
|
||
|
FT_EXPORT( FT_Error )
|
||
|
FTC_MruList_Lookup( FTC_MruList list,
|
||
|
FT_Pointer key,
|
||
|
FTC_MruNode *anode )
|
||
|
{
|
||
|
FT_Memory memory = list->memory;
|
||
|
FTC_MruNode_CompareFunc compare = list->clazz.node_compare;
|
||
|
FTC_MruNode *plast, *pnode, *pfirst;
|
||
|
FTC_MruNode node;
|
||
|
FT_Error error = 0;
|
||
|
|
||
|
pfirst = &list->nodes;
|
||
|
plast = pnode = pfirst;
|
||
|
|
||
|
for (;;)
|
||
|
{
|
||
|
node = *pnode;
|
||
|
if ( node == NULL )
|
||
|
goto NewNode;
|
||
|
if ( compare( node, key ) )
|
||
|
break;
|
||
|
plast = pnode;
|
||
|
pnode = &node->next;
|
||
|
}
|
||
|
|
||
|
if ( node != *pfirst )
|
||
|
{
|
||
|
*pnode = node->next;
|
||
|
node->next = *pfirst;
|
||
|
*pfirst = node;
|
||
|
}
|
||
|
goto Exit;
|
||
|
|
||
|
NewNode:
|
||
|
if ( list->max_nodes > 0 && list->num_nodes >= list->max_nodes )
|
||
|
{
|
||
|
node = *plast;
|
||
|
|
||
|
if ( node )
|
||
|
{
|
||
|
*plast = NULL;
|
||
|
list->num_nodes--;
|
||
|
|
||
|
if ( list->clazz.node_reset )
|
||
|
{
|
||
|
error = list->clazz.node_reset( node, key, list->data );
|
||
|
if ( !error ) goto AddNode;
|
||
|
}
|
||
|
|
||
|
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 )
|
||
|
{
|
||
|
if ( list->clazz.node_done )
|
||
|
list->clazz.node_done( node, list->data );
|
||
|
|
||
|
FT_FREE( node );
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
AddNode:
|
||
|
node->next = list->nodes;
|
||
|
list->nodes = node;
|
||
|
list->num_nodes++;
|
||
|
|
||
|
Exit:
|
||
|
*anode = node;
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
|
||
|
FT_EXPORT_DEF( void )
|
||
|
FTC_MruList_Remove( FTC_MruList list,
|
||
|
FTC_MruNode node )
|
||
|
{
|
||
|
FTC_MruNode *pnode = &list->nodes;
|
||
|
|
||
|
for ( ;; )
|
||
|
{
|
||
|
if ( *pnode == NULL ) /* should not happen !! */
|
||
|
{
|
||
|
FT_ERROR(( "%s: trying to remove unknown node !!\n",
|
||
|
"FTC_MruList_Remove" ));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( *pnode == node )
|
||
|
break;
|
||
|
|
||
|
pnode = &node->next;
|
||
|
}
|
||
|
|
||
|
*pnode = node->next;
|
||
|
node->next = NULL;
|
||
|
list->num_nodes--;
|
||
|
|
||
|
{
|
||
|
FT_Memory memory = list->memory;
|
||
|
|
||
|
if ( list->clazz.node_done )
|
||
|
list->clazz.node_done( node, list->data );
|
||
|
|
||
|
FT_FREE( node );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
FT_EXPORT_DEF( void )
|
||
|
FTC_MruList_RemoveSelection( FTC_MruList list,
|
||
|
FTC_MruNode_CompareFunc select,
|
||
|
FT_Pointer key )
|
||
|
{
|
||
|
FTC_MruNode *pnode = &list->nodes;
|
||
|
FTC_MruNode node, free = NULL;;
|
||
|
|
||
|
if ( select )
|
||
|
{
|
||
|
for (;;)
|
||
|
{
|
||
|
FTC_MruNode node = *pnode;
|
||
|
|
||
|
if ( node == NULL )
|
||
|
break;
|
||
|
|
||
|
if ( select( node, key ) )
|
||
|
{
|
||
|
*pnode = node->next;
|
||
|
node->next = free;
|
||
|
free = node;
|
||
|
}
|
||
|
else
|
||
|
pnode = &node->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ftc_mrulist_free_nodes( list, &free );
|
||
|
}
|
||
|
|
||
|
/* END */
|
||
|
|