PageRenderTime 76ms CodeModel.GetById 48ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/src/compiler/android-ndk/jni/freetype/src/base/ftutil.c

http://ftk.googlecode.com/
C | 501 lines | 313 code | 125 blank | 63 comment | 49 complexity | 708a2cd5d3ebb1bc3443de79cd7b2e3e MD5 | raw file
  1/***************************************************************************/
  2/*                                                                         */
  3/*  ftutil.c                                                               */
  4/*                                                                         */
  5/*    FreeType utility file for memory and list management (body).         */
  6/*                                                                         */
  7/*  Copyright 2002, 2004, 2005, 2006, 2007 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_INTERNAL_OBJECTS_H
 23#include FT_LIST_H
 24
 25
 26  /*************************************************************************/
 27  /*                                                                       */
 28  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
 29  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
 30  /* messages during execution.                                            */
 31  /*                                                                       */
 32#undef  FT_COMPONENT
 33#define FT_COMPONENT  trace_memory
 34
 35
 36  /*************************************************************************/
 37  /*************************************************************************/
 38  /*************************************************************************/
 39  /*****                                                               *****/
 40  /*****                                                               *****/
 41  /*****               M E M O R Y   M A N A G E M E N T               *****/
 42  /*****                                                               *****/
 43  /*****                                                               *****/
 44  /*************************************************************************/
 45  /*************************************************************************/
 46  /*************************************************************************/
 47
 48
 49  FT_BASE_DEF( FT_Pointer )
 50  ft_mem_alloc( FT_Memory  memory,
 51                FT_Long    size,
 52                FT_Error  *p_error )
 53  {
 54    FT_Error    error;
 55    FT_Pointer  block = ft_mem_qalloc( memory, size, &error );
 56
 57    if ( !error && size > 0 )
 58      FT_MEM_ZERO( block, size );
 59
 60    *p_error = error;
 61    return block;
 62  }
 63
 64
 65  FT_BASE_DEF( FT_Pointer )
 66  ft_mem_qalloc( FT_Memory  memory,
 67                 FT_Long    size,
 68                 FT_Error  *p_error )
 69  {
 70    FT_Error    error = FT_Err_Ok;
 71    FT_Pointer  block = NULL;
 72
 73
 74    if ( size > 0 )
 75    {
 76      block = memory->alloc( memory, size );
 77      if ( block == NULL )
 78        error = FT_Err_Out_Of_Memory;
 79    }
 80    else if ( size < 0 )
 81    {
 82      /* may help catch/prevent security issues */
 83      error = FT_Err_Invalid_Argument;
 84    }
 85
 86    *p_error = error;
 87    return block;
 88  }
 89
 90
 91  FT_BASE_DEF( FT_Pointer )
 92  ft_mem_realloc( FT_Memory  memory,
 93                  FT_Long    item_size,
 94                  FT_Long    cur_count,
 95                  FT_Long    new_count,
 96                  void*      block,
 97                  FT_Error  *p_error )
 98  {
 99    FT_Error  error = FT_Err_Ok;
100
101    block = ft_mem_qrealloc( memory, item_size,
102                             cur_count, new_count, block, &error );
103    if ( !error && new_count > cur_count )
104      FT_MEM_ZERO( (char*)block + cur_count * item_size,
105                   ( new_count - cur_count ) * item_size );
106
107    *p_error = error;
108    return block;
109  }
110
111
112  FT_BASE_DEF( FT_Pointer )
113  ft_mem_qrealloc( FT_Memory  memory,
114                   FT_Long    item_size,
115                   FT_Long    cur_count,
116                   FT_Long    new_count,
117                   void*      block,
118                   FT_Error  *p_error )
119  {
120    FT_Error  error = FT_Err_Ok;
121
122
123    /* Note that we now accept `item_size == 0' as a valid parameter, in
124     * order to cover very weird cases where an ALLOC_MULT macro would be
125     * called.
126     */
127    if ( cur_count < 0 || new_count < 0 || item_size < 0 )
128    {
129      /* may help catch/prevent nasty security issues */
130      error = FT_Err_Invalid_Argument;
131    }
132    else if ( new_count == 0 || item_size == 0 )
133    {
134      ft_mem_free( memory, block );
135      block = NULL;
136    }
137    else if ( new_count > FT_INT_MAX/item_size )
138    {
139      error = FT_Err_Array_Too_Large;
140    }
141    else if ( cur_count == 0 )
142    {
143      FT_ASSERT( block == NULL );
144
145      block = ft_mem_alloc( memory, new_count*item_size, &error );
146    }
147    else
148    {
149      FT_Pointer  block2;
150      FT_Long     cur_size = cur_count*item_size;
151      FT_Long     new_size = new_count*item_size;
152
153
154      block2 = memory->realloc( memory, cur_size, new_size, block );
155      if ( block2 == NULL )
156        error = FT_Err_Out_Of_Memory;
157      else
158        block = block2;
159    }
160
161    *p_error = error;
162    return block;
163  }
164
165
166  FT_BASE_DEF( void )
167  ft_mem_free( FT_Memory   memory,
168               const void *P )
169  {
170    if ( P )
171      memory->free( memory, (void*)P );
172  }
173
174
175  FT_BASE_DEF( FT_Pointer )
176  ft_mem_dup( FT_Memory    memory,
177              const void*  address,
178              FT_ULong     size,
179              FT_Error    *p_error )
180  {
181    FT_Error    error;
182    FT_Pointer  p = ft_mem_qalloc( memory, size, &error );
183
184
185    if ( !error && address )
186      ft_memcpy( p, address, size );
187
188    *p_error = error;
189    return p;
190  }
191
192
193  FT_BASE_DEF( FT_Pointer )
194  ft_mem_strdup( FT_Memory    memory,
195                 const char*  str,
196                 FT_Error    *p_error )
197  {
198    FT_ULong  len = str ? (FT_ULong)ft_strlen( str ) + 1
199                        : 0;
200
201
202    return ft_mem_dup( memory, str, len, p_error );
203  }
204
205
206  FT_BASE_DEF( FT_Int )
207  ft_mem_strcpyn( char*        dst,
208                  const char*  src,
209                  FT_ULong     size )
210  {
211    while ( size > 1 && *src != 0 )
212    {
213      *dst++ = *src++;
214      size--;
215    }
216
217    *dst = 0;  /* always zero-terminate */
218
219    return *src != 0;
220  }
221
222
223  /*************************************************************************/
224  /*************************************************************************/
225  /*************************************************************************/
226  /*****                                                               *****/
227  /*****                                                               *****/
228  /*****            D O U B L Y   L I N K E D   L I S T S              *****/
229  /*****                                                               *****/
230  /*****                                                               *****/
231  /*************************************************************************/
232  /*************************************************************************/
233  /*************************************************************************/
234
235#undef  FT_COMPONENT
236#define FT_COMPONENT  trace_list
237
238  /* documentation is in ftlist.h */
239
240  FT_EXPORT_DEF( FT_ListNode )
241  FT_List_Find( FT_List  list,
242                void*    data )
243  {
244    FT_ListNode  cur;
245
246
247    cur = list->head;
248    while ( cur )
249    {
250      if ( cur->data == data )
251        return cur;
252
253      cur = cur->next;
254    }
255
256    return (FT_ListNode)0;
257  }
258
259
260  /* documentation is in ftlist.h */
261
262  FT_EXPORT_DEF( void )
263  FT_List_Add( FT_List      list,
264               FT_ListNode  node )
265  {
266    FT_ListNode  before = list->tail;
267
268
269    node->next = 0;
270    node->prev = before;
271
272    if ( before )
273      before->next = node;
274    else
275      list->head = node;
276
277    list->tail = node;
278  }
279
280
281  /* documentation is in ftlist.h */
282
283  FT_EXPORT_DEF( void )
284  FT_List_Insert( FT_List      list,
285                  FT_ListNode  node )
286  {
287    FT_ListNode  after = list->head;
288
289
290    node->next = after;
291    node->prev = 0;
292
293    if ( !after )
294      list->tail = node;
295    else
296      after->prev = node;
297
298    list->head = node;
299  }
300
301
302  /* documentation is in ftlist.h */
303
304  FT_EXPORT_DEF( void )
305  FT_List_Remove( FT_List      list,
306                  FT_ListNode  node )
307  {
308    FT_ListNode  before, after;
309
310
311    before = node->prev;
312    after  = node->next;
313
314    if ( before )
315      before->next = after;
316    else
317      list->head = after;
318
319    if ( after )
320      after->prev = before;
321    else
322      list->tail = before;
323  }
324
325
326  /* documentation is in ftlist.h */
327
328  FT_EXPORT_DEF( void )
329  FT_List_Up( FT_List      list,
330              FT_ListNode  node )
331  {
332    FT_ListNode  before, after;
333
334
335    before = node->prev;
336    after  = node->next;
337
338    /* check whether we are already on top of the list */
339    if ( !before )
340      return;
341
342    before->next = after;
343
344    if ( after )
345      after->prev = before;
346    else
347      list->tail = before;
348
349    node->prev       = 0;
350    node->next       = list->head;
351    list->head->prev = node;
352    list->head       = node;
353  }
354
355
356  /* documentation is in ftlist.h */
357
358  FT_EXPORT_DEF( FT_Error )
359  FT_List_Iterate( FT_List            list,
360                   FT_List_Iterator   iterator,
361                   void*              user )
362  {
363    FT_ListNode  cur   = list->head;
364    FT_Error     error = FT_Err_Ok;
365
366
367    while ( cur )
368    {
369      FT_ListNode  next = cur->next;
370
371
372      error = iterator( cur, user );
373      if ( error )
374        break;
375
376      cur = next;
377    }
378
379    return error;
380  }
381
382
383  /* documentation is in ftlist.h */
384
385  FT_EXPORT_DEF( void )
386  FT_List_Finalize( FT_List             list,
387                    FT_List_Destructor  destroy,
388                    FT_Memory           memory,
389                    void*               user )
390  {
391    FT_ListNode  cur;
392
393
394    cur = list->head;
395    while ( cur )
396    {
397      FT_ListNode  next = cur->next;
398      void*        data = cur->data;
399
400
401      if ( destroy )
402        destroy( memory, data, user );
403
404      FT_FREE( cur );
405      cur = next;
406    }
407
408    list->head = 0;
409    list->tail = 0;
410  }
411
412
413  FT_BASE_DEF( FT_UInt32 )
414  ft_highpow2( FT_UInt32  value )
415  {
416    FT_UInt32  value2;
417
418
419    /*
420     *  We simply clear the lowest bit in each iteration.  When
421     *  we reach 0, we know that the previous value was our result.
422     */
423    for ( ;; )
424    {
425      value2 = value & (value - 1);  /* clear lowest bit */
426      if ( value2 == 0 )
427        break;
428
429      value = value2;
430    }
431    return value;
432  }
433
434
435#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
436
437  FT_BASE_DEF( FT_Error )
438  FT_Alloc( FT_Memory  memory,
439            FT_Long    size,
440            void*     *P )
441  {
442    FT_Error  error;
443
444
445    (void)FT_ALLOC( *P, size );
446    return error;
447  }
448
449
450  FT_BASE_DEF( FT_Error )
451  FT_QAlloc( FT_Memory  memory,
452             FT_Long    size,
453             void*     *p )
454  {
455    FT_Error  error;
456
457
458    (void)FT_QALLOC( *p, size );
459    return error;
460  }
461
462
463  FT_BASE_DEF( FT_Error )
464  FT_Realloc( FT_Memory  memory,
465              FT_Long    current,
466              FT_Long    size,
467              void*     *P )
468  {
469    FT_Error  error;
470
471
472    (void)FT_REALLOC( *P, current, size );
473    return error;
474  }
475
476
477  FT_BASE_DEF( FT_Error )
478  FT_QRealloc( FT_Memory  memory,
479               FT_Long    current,
480               FT_Long    size,
481               void*     *p )
482  {
483    FT_Error  error;
484
485
486    (void)FT_QREALLOC( *p, current, size );
487    return error;
488  }
489
490
491  FT_BASE_DEF( void )
492  FT_Free( FT_Memory  memory,
493           void*     *P )
494  {
495    if ( *P )
496      FT_MEM_FREE( *P );
497  }
498
499#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
500
501/* END */