This commit was manufactured by cvs2svn to create branch 'captive'.
[reactos.git] / lib / freetype / src / base / ftutil.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftutil.c                                                               */
4 /*                                                                         */
5 /*    FreeType utility file for memory and list management (body).         */
6 /*                                                                         */
7 /*  Copyright 2002 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_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_MEMORY_H
22 #include FT_LIST_H
23
24
25   /*************************************************************************/
26   /*                                                                       */
27   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
28   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
29   /* messages during execution.                                            */
30   /*                                                                       */
31 #undef  FT_COMPONENT
32 #define FT_COMPONENT  trace_memory
33
34
35   /*************************************************************************/
36   /*************************************************************************/
37   /*************************************************************************/
38   /*****                                                               *****/
39   /*****                                                               *****/
40   /*****               M E M O R Y   M A N A G E M E N T               *****/
41   /*****                                                               *****/
42   /*****                                                               *****/
43   /*************************************************************************/
44   /*************************************************************************/
45   /*************************************************************************/
46
47   /* documentation is in ftmemory.h */
48
49   FT_BASE_DEF( FT_Error )
50   FT_Alloc( FT_Memory  memory,
51             FT_Long    size,
52             void*     *P )
53   {
54     FT_ASSERT( P != 0 );
55
56     if ( size > 0 )
57     {
58       *P = memory->alloc( memory, size );
59       if ( !*P )
60       {
61         FT_ERROR(( "FT_Alloc:" ));
62         FT_ERROR(( " Out of memory? (%ld requested)\n",
63                    size ));
64
65         return FT_Err_Out_Of_Memory;
66       }
67       FT_MEM_ZERO( *P, size );
68     }
69     else
70       *P = NULL;
71
72     FT_TRACE7(( "FT_Alloc:" ));
73     FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n",
74                 size, *P, P ));
75
76     return FT_Err_Ok;
77   }
78
79
80   /* documentation is in ftmemory.h */
81
82   FT_BASE_DEF( FT_Error )
83   FT_Realloc( FT_Memory  memory,
84               FT_Long    current,
85               FT_Long    size,
86               void**     P )
87   {
88     void*  Q;
89
90
91     FT_ASSERT( P != 0 );
92
93     /* if the original pointer is NULL, call FT_Alloc() */
94     if ( !*P )
95       return FT_Alloc( memory, size, P );
96
97     /* if the new block if zero-sized, clear the current one */
98     if ( size <= 0 )
99     {
100       FT_Free( memory, P );
101       return FT_Err_Ok;
102     }
103
104     Q = memory->realloc( memory, current, size, *P );
105     if ( !Q )
106       goto Fail;
107
108     if ( size > current )
109       FT_MEM_ZERO( (char*)Q + current, size - current );
110
111     *P = Q;
112     return FT_Err_Ok;
113
114   Fail:
115     FT_ERROR(( "FT_Realloc:" ));
116     FT_ERROR(( " Failed (current %ld, requested %ld)\n",
117                current, size ));
118     return FT_Err_Out_Of_Memory;
119   }
120
121
122   /* documentation is in ftmemory.h */
123
124   FT_BASE_DEF( void )
125   FT_Free( FT_Memory  memory,
126            void**     P )
127   {
128     FT_TRACE7(( "FT_Free:" ));
129     FT_TRACE7(( " Freeing block 0x%08p, ref 0x%08p\n",
130                 P, P ? *P : (void*)0 ));
131
132     if ( P && *P )
133     {
134       memory->free( memory, *P );
135       *P = 0;
136     }
137   }
138
139
140   /*************************************************************************/
141   /*************************************************************************/
142   /*************************************************************************/
143   /*****                                                               *****/
144   /*****                                                               *****/
145   /*****            D O U B L Y   L I N K E D   L I S T S              *****/
146   /*****                                                               *****/
147   /*****                                                               *****/
148   /*************************************************************************/
149   /*************************************************************************/
150   /*************************************************************************/
151
152 #undef  FT_COMPONENT
153 #define FT_COMPONENT  trace_list
154
155   /* documentation is in ftlist.h */
156
157   FT_EXPORT_DEF( FT_ListNode )
158   FT_List_Find( FT_List  list,
159                 void*    data )
160   {
161     FT_ListNode  cur;
162
163
164     cur = list->head;
165     while ( cur )
166     {
167       if ( cur->data == data )
168         return cur;
169
170       cur = cur->next;
171     }
172
173     return (FT_ListNode)0;
174   }
175
176
177   /* documentation is in ftlist.h */
178
179   FT_EXPORT_DEF( void )
180   FT_List_Add( FT_List      list,
181                FT_ListNode  node )
182   {
183     FT_ListNode  before = list->tail;
184
185
186     node->next = 0;
187     node->prev = before;
188
189     if ( before )
190       before->next = node;
191     else
192       list->head = node;
193
194     list->tail = node;
195   }
196
197
198   /* documentation is in ftlist.h */
199
200   FT_EXPORT_DEF( void )
201   FT_List_Insert( FT_List      list,
202                   FT_ListNode  node )
203   {
204     FT_ListNode  after = list->head;
205
206
207     node->next = after;
208     node->prev = 0;
209
210     if ( !after )
211       list->tail = node;
212     else
213       after->prev = node;
214
215     list->head = node;
216   }
217
218
219   /* documentation is in ftlist.h */
220
221   FT_EXPORT_DEF( void )
222   FT_List_Remove( FT_List      list,
223                   FT_ListNode  node )
224   {
225     FT_ListNode  before, after;
226
227
228     before = node->prev;
229     after  = node->next;
230
231     if ( before )
232       before->next = after;
233     else
234       list->head = after;
235
236     if ( after )
237       after->prev = before;
238     else
239       list->tail = before;
240   }
241
242
243   /* documentation is in ftlist.h */
244
245   FT_EXPORT_DEF( void )
246   FT_List_Up( FT_List      list,
247               FT_ListNode  node )
248   {
249     FT_ListNode  before, after;
250
251
252     before = node->prev;
253     after  = node->next;
254
255     /* check whether we are already on top of the list */
256     if ( !before )
257       return;
258
259     before->next = after;
260
261     if ( after )
262       after->prev = before;
263     else
264       list->tail = before;
265
266     node->prev       = 0;
267     node->next       = list->head;
268     list->head->prev = node;
269     list->head       = node;
270   }
271
272
273   /* documentation is in ftlist.h */
274
275   FT_EXPORT_DEF( FT_Error )
276   FT_List_Iterate( FT_List            list,
277                    FT_List_Iterator   iterator,
278                    void*              user )
279   {
280     FT_ListNode  cur   = list->head;
281     FT_Error     error = FT_Err_Ok;
282
283
284     while ( cur )
285     {
286       FT_ListNode  next = cur->next;
287
288
289       error = iterator( cur, user );
290       if ( error )
291         break;
292
293       cur = next;
294     }
295
296     return error;
297   }
298
299
300   /* documentation is in ftlist.h */
301
302   FT_EXPORT_DEF( void )
303   FT_List_Finalize( FT_List             list,
304                     FT_List_Destructor  destroy,
305                     FT_Memory           memory,
306                     void*               user )
307   {
308     FT_ListNode  cur;
309
310
311     cur = list->head;
312     while ( cur )
313     {
314       FT_ListNode  next = cur->next;
315       void*        data = cur->data;
316
317
318       if ( destroy )
319         destroy( memory, data, user );
320
321       FT_FREE( cur );
322       cur = next;
323     }
324
325     list->head = 0;
326     list->tail = 0;
327   }
328
329
330 /* END */