source: trunk/poppler/freetype-2.1.10/src/cache/ftcmru.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 16 years ago

First import

File size: 7.5 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  ftcmru.c                                                               */
4/*                                                                         */
5/*    FreeType MRU support (body).                                         */
6/*                                                                         */
7/*  Copyright 2003, 2004 by                                                */
8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9/*                                                                         */
10/*  This file is part of the FreeType project, and may only be used,       */
11/*  modified, and distributed under the terms of the FreeType project      */
12/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13/*  this file you indicate that you have read the license and              */
14/*  understand and accept it fully.                                        */
15/*                                                                         */
16/***************************************************************************/
17
18
19#include <ft2build.h>
20#include FT_CACHE_H
21#include FT_CACHE_INTERNAL_MRU_H
22#include FT_INTERNAL_OBJECTS_H
23#include FT_INTERNAL_DEBUG_H
24
25#include "ftcerror.h"
26
27
28  FT_EXPORT_DEF( void )
29  FTC_MruNode_Prepend( FTC_MruNode  *plist,
30                       FTC_MruNode   node )
31  {
32    FTC_MruNode  first = *plist;
33
34
35    if ( first )
36    {
37      FTC_MruNode  last = first->prev;
38
39
40#ifdef FT_DEBUG_ERROR
41      {
42        FTC_MruNode  cnode = first;
43
44
45        do
46        {
47          if ( cnode == node )
48          {
49            fprintf( stderr, "FTC_MruNode_Prepend: invalid action!\n" );
50            exit( 2 );
51          }
52          cnode = cnode->next;
53
54        } while ( cnode != first );
55      }
56#endif
57
58      first->prev = node;
59      last->next  = node;
60      node->next  = first;
61      node->prev  = last;
62    }
63    else
64    {
65      node->next = node;
66      node->prev = node;
67    }
68    *plist = node;
69  }
70
71
72  FT_EXPORT_DEF( void )
73  FTC_MruNode_Up( FTC_MruNode  *plist,
74                  FTC_MruNode   node )
75  {
76    FTC_MruNode  first = *plist;
77
78
79    FT_ASSERT( first != NULL );
80
81    if ( first != node )
82    {
83      FTC_MruNode  prev, next, last;
84
85
86#ifdef FT_DEBUG_ERROR
87      {
88        FTC_MruNode  cnode = first;
89        do
90        {
91          if ( cnode == node )
92            goto Ok;
93          cnode = cnode->next;
94
95        } while ( cnode != first );
96
97        fprintf( stderr, "FTC_MruNode_Up: invalid action!\n" );
98        exit( 2 );
99      Ok:
100      }
101#endif
102      prev = node->prev;
103      next = node->next;
104
105      prev->next = next;
106      next->prev = prev;
107
108      last = first->prev;
109
110      last->next  = node;
111      first->prev = node;
112
113      node->next = first;
114      node->prev = last;
115
116      *plist = node;
117    }
118  }
119
120
121  FT_EXPORT_DEF( void )
122  FTC_MruNode_Remove( FTC_MruNode  *plist,
123                      FTC_MruNode   node )
124  {
125    FTC_MruNode  first = *plist;
126    FTC_MruNode  prev, next;
127
128
129    FT_ASSERT( first != NULL );
130
131#ifdef FT_DEBUG_ERROR
132      {
133        FTC_MruNode  cnode = first;
134
135
136        do
137        {
138          if ( cnode == node )
139            goto Ok;
140          cnode = cnode->next;
141
142        } while ( cnode != first );
143
144        fprintf( stderr, "FTC_MruNode_Remove: invalid action!\n" );
145        exit( 2 );
146      Ok:
147      }
148#endif
149
150    prev = node->prev;
151    next = node->next;
152
153    prev->next = next;
154    next->prev = prev;
155
156    if ( node == next )
157    {
158      FT_ASSERT( first == node );
159      FT_ASSERT( prev  == node );
160
161      *plist = NULL;
162    }
163    else if ( node == first )
164        *plist = next;
165  }
166
167
168  FT_EXPORT_DEF( void )
169  FTC_MruList_Init( FTC_MruList       list,
170                    FTC_MruListClass  clazz,
171                    FT_UInt           max_nodes,
172                    FT_Pointer        data,
173                    FT_Memory         memory )
174  {
175    list->num_nodes = 0;
176    list->max_nodes = max_nodes;
177    list->nodes     = NULL;
178    list->clazz     = *clazz;
179    list->data      = data;
180    list->memory    = memory;
181  }
182
183
184  FT_EXPORT( void )
185  FTC_MruList_Reset( FTC_MruList  list )
186  {
187    while ( list->nodes )
188      FTC_MruList_Remove( list, list->nodes );
189
190    FT_ASSERT( list->num_nodes == 0 );
191  }
192
193
194  FT_EXPORT( void )
195  FTC_MruList_Done( FTC_MruList  list )
196  {
197    FTC_MruList_Reset( list );
198  }
199
200
201  FT_EXPORT_DEF( FTC_MruNode )
202  FTC_MruList_Find( FTC_MruList  list,
203                    FT_Pointer   key )
204  {
205    FTC_MruNode_CompareFunc  compare = list->clazz.node_compare;
206    FTC_MruNode              first, node;
207
208
209    first = list->nodes;
210    node  = NULL;
211
212    if ( first )
213    {
214      node = first;
215      do
216      {
217        if ( compare( node, key ) )
218        {
219          if ( node != first )
220            FTC_MruNode_Up( &list->nodes, node );
221
222          return node;
223        }
224
225        node = node->next;
226
227      } while ( node != first);
228    }
229
230    return NULL;
231  }
232
233
234  FT_EXPORT_DEF( FT_Error )
235  FTC_MruList_New( FTC_MruList   list,
236                   FT_Pointer    key,
237                   FTC_MruNode  *anode )
238  {
239    FT_Error     error;
240    FTC_MruNode  node;
241    FT_Memory    memory = list->memory;
242
243
244    if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )
245    {
246      node = list->nodes->prev;
247
248      FT_ASSERT( node );
249
250      if ( list->clazz.node_reset )
251      {
252        FTC_MruNode_Up( &list->nodes, node );
253
254        error = list->clazz.node_reset( node, key, list->data );
255        if ( !error )
256          goto Exit;
257      }
258
259      FTC_MruNode_Remove( &list->nodes, node );
260      list->num_nodes--;
261
262      if ( list->clazz.node_done )
263        list->clazz.node_done( node, list->data );
264    }
265    else if ( FT_ALLOC( node, list->clazz.node_size ) )
266        goto Exit;
267
268    error = list->clazz.node_init( node, key, list->data );
269    if ( error )
270      goto Fail;
271
272      FTC_MruNode_Prepend( &list->nodes, node );
273      list->num_nodes++;
274
275  Exit:
276    *anode = node;
277    return error;
278
279  Fail:
280    if ( list->clazz.node_done )
281      list->clazz.node_done( node, list->data );
282
283    FT_FREE( node );
284    goto Exit;
285  }
286
287
288  FT_EXPORT( FT_Error )
289  FTC_MruList_Lookup( FTC_MruList   list,
290                      FT_Pointer    key,
291                      FTC_MruNode  *anode )
292  {
293    FTC_MruNode  node;
294
295
296    node = FTC_MruList_Find( list, key );
297    if ( node == NULL )
298      return FTC_MruList_New( list, key, anode );
299
300    *anode = node;
301    return 0;
302  }
303
304
305  FT_EXPORT_DEF( void )
306  FTC_MruList_Remove( FTC_MruList  list,
307                      FTC_MruNode  node )
308  {
309    FTC_MruNode_Remove( &list->nodes, node );
310    list->num_nodes--;
311
312    {
313      FT_Memory  memory = list->memory;
314
315
316      if ( list->clazz.node_done )
317       list->clazz.node_done( node, list->data );
318
319      FT_FREE( node );
320    }
321  }
322
323
324  FT_EXPORT_DEF( void )
325  FTC_MruList_RemoveSelection( FTC_MruList              list,
326                               FTC_MruNode_CompareFunc  selection,
327                               FT_Pointer               key )
328  {
329    FTC_MruNode  first, node, next;
330
331
332    first = list->nodes;
333    while ( first && ( selection == NULL || selection( first, key ) ) )
334    {
335      FTC_MruList_Remove( list, first );
336      first = list->nodes;
337    }
338
339    if ( first )
340    {
341      node = first->next;
342      while ( node != first )
343      {
344        next = node->next;
345
346        if ( selection( node, key ) )
347          FTC_MruList_Remove( list, node );
348
349        node = next;
350      }
351    }
352  }
353
354
355/* END */
Note: See TracBrowser for help on using the repository browser.