Initialize Tizen 2.3
[framework/graphics/freetype.git] / src / cache / ftcmru.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftcmru.c                                                               */
4 /*                                                                         */
5 /*    FreeType MRU support (body).                                         */
6 /*                                                                         */
7 /*  Copyright 2003, 2004, 2006, 2009 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 "ftcmru.h"
22 #include FT_INTERNAL_OBJECTS_H
23 #include FT_INTERNAL_DEBUG_H
24
25 #include "ftcerror.h"
26
27
28   FT_LOCAL_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_LOCAL_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_LOCAL_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_LOCAL_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_LOCAL_DEF( 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_LOCAL_DEF( void )
195   FTC_MruList_Done( FTC_MruList  list )
196   {
197     FTC_MruList_Reset( list );
198   }
199
200
201 #ifndef FTC_INLINE
202   FT_LOCAL_DEF( FTC_MruNode )
203   FTC_MruList_Find( FTC_MruList  list,
204                     FT_Pointer   key )
205   {
206     FTC_MruNode_CompareFunc  compare = list->clazz.node_compare;
207     FTC_MruNode              first, node;
208
209
210     first = list->nodes;
211     node  = NULL;
212
213     if ( first )
214     {
215       node = first;
216       do
217       {
218         if ( compare( node, key ) )
219         {
220           if ( node != first )
221             FTC_MruNode_Up( &list->nodes, node );
222
223           return node;
224         }
225
226         node = node->next;
227
228       } while ( node != first);
229     }
230
231     return NULL;
232   }
233 #endif
234
235   FT_LOCAL_DEF( FT_Error )
236   FTC_MruList_New( FTC_MruList   list,
237                    FT_Pointer    key,
238                    FTC_MruNode  *anode )
239   {
240     FT_Error     error;
241     FTC_MruNode  node = NULL;
242     FT_Memory    memory = list->memory;
243
244
245     if ( list->num_nodes >= list->max_nodes && list->max_nodes > 0 )
246     {
247       node = list->nodes->prev;
248
249       FT_ASSERT( node );
250
251       if ( list->clazz.node_reset )
252       {
253         FTC_MruNode_Up( &list->nodes, node );
254
255         error = list->clazz.node_reset( node, key, list->data );
256         if ( !error )
257           goto Exit;
258       }
259
260       FTC_MruNode_Remove( &list->nodes, node );
261       list->num_nodes--;
262
263       if ( list->clazz.node_done )
264         list->clazz.node_done( node, list->data );
265     }
266     else if ( FT_ALLOC( node, list->clazz.node_size ) )
267       goto Exit;
268
269     error = list->clazz.node_init( node, key, list->data );
270     if ( error )
271       goto Fail;
272
273     FTC_MruNode_Prepend( &list->nodes, node );
274     list->num_nodes++;
275
276   Exit:
277     *anode = node;
278     return error;
279
280   Fail:
281     if ( list->clazz.node_done )
282       list->clazz.node_done( node, list->data );
283
284     FT_FREE( node );
285     goto Exit;
286   }
287
288
289 #ifndef FTC_INLINE
290   FT_LOCAL_DEF( FT_Error )
291   FTC_MruList_Lookup( FTC_MruList   list,
292                       FT_Pointer    key,
293                       FTC_MruNode  *anode )
294   {
295     FTC_MruNode  node;
296
297
298     node = FTC_MruList_Find( list, key );
299     if ( node == NULL )
300       return FTC_MruList_New( list, key, anode );
301
302     *anode = node;
303     return 0;
304   }
305 #endif /* FTC_INLINE */
306
307   FT_LOCAL_DEF( void )
308   FTC_MruList_Remove( FTC_MruList  list,
309                       FTC_MruNode  node )
310   {
311     FTC_MruNode_Remove( &list->nodes, node );
312     list->num_nodes--;
313
314     {
315       FT_Memory  memory = list->memory;
316
317
318       if ( list->clazz.node_done )
319         list->clazz.node_done( node, list->data );
320
321       FT_FREE( node );
322     }
323   }
324
325
326   FT_LOCAL_DEF( void )
327   FTC_MruList_RemoveSelection( FTC_MruList              list,
328                                FTC_MruNode_CompareFunc  selection,
329                                FT_Pointer               key )
330   {
331     FTC_MruNode  first, node, next;
332
333
334     first = list->nodes;
335     while ( first && ( selection == NULL || selection( first, key ) ) )
336     {
337       FTC_MruList_Remove( list, first );
338       first = list->nodes;
339     }
340
341     if ( first )
342     {
343       node = first->next;
344       while ( node != first )
345       {
346         next = node->next;
347
348         if ( selection( node, key ) )
349           FTC_MruList_Remove( list, node );
350
351         node = next;
352       }
353     }
354   }
355
356
357 /* END */