Edit

kc3-lang/freetype/src/base/ftutil.c

Branch :

  • Show log

    Commit

  • Author : Werner Lemberg
    Date : 2006-06-04 15:17:41
    Hash : d724f20e
    Message : formatting

  • src/base/ftutil.c
  • /***************************************************************************/
    /*                                                                         */
    /*  ftutil.c                                                               */
    /*                                                                         */
    /*    FreeType utility file for memory and list management (body).         */
    /*                                                                         */
    /*  Copyright 2002, 2004, 2005, 2006 by                                    */
    /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
    /*                                                                         */
    /*  This file is part of the FreeType project, and may only be used,       */
    /*  modified, and distributed under the terms of the FreeType project      */
    /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
    /*  this file you indicate that you have read the license and              */
    /*  understand and accept it fully.                                        */
    /*                                                                         */
    /***************************************************************************/
    
    
    #include <ft2build.h>
    #include FT_INTERNAL_DEBUG_H
    #include FT_INTERNAL_MEMORY_H
    #include FT_INTERNAL_OBJECTS_H
    #include FT_LIST_H
    
    
      /*************************************************************************/
      /*                                                                       */
      /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
      /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
      /* messages during execution.                                            */
      /*                                                                       */
    #undef  FT_COMPONENT
    #define FT_COMPONENT  trace_memory
    
    
      /*************************************************************************/
      /*************************************************************************/
      /*************************************************************************/
      /*****                                                               *****/
      /*****                                                               *****/
      /*****               M E M O R Y   M A N A G E M E N T               *****/
      /*****                                                               *****/
      /*****                                                               *****/
      /*************************************************************************/
      /*************************************************************************/
      /*************************************************************************/
    
    
      FT_BASE_DEF( FT_Pointer )
      ft_mem_alloc( FT_Memory  memory,
                    FT_Long    size,
                    FT_Error  *p_error )
      {
        FT_Error    error;
        FT_Pointer  block = ft_mem_qalloc( memory, size, &error );
    
        if ( !error && size > 0 )
          FT_MEM_ZERO( block, size );
    
        *p_error = error;
        return block;
      }
    
    
      FT_BASE_DEF( FT_Pointer )
      ft_mem_qalloc( FT_Memory  memory,
                     FT_Long    size,
                     FT_Error  *p_error )
      {
        FT_Error    error = FT_Err_Ok;
        FT_Pointer  block = NULL;
    
    
        if ( size > 0 )
        {
          block = memory->alloc( memory, size );
          if ( block == NULL )
            error = FT_Err_Out_Of_Memory;
        }
        else if ( size < 0 )
        {
          /* may help catch/prevent security issues */
          error = FT_Err_Invalid_Argument;
        }
    
        *p_error = error;
        return block;
      }
    
    
      FT_BASE_DEF( FT_Pointer )
      ft_mem_realloc( FT_Memory  memory,
                      FT_Long    item_size,
                      FT_Long    cur_count,
                      FT_Long    new_count,
                      void*      block,
                      FT_Error  *p_error )
      {
        FT_Error  error = FT_Err_Ok;
    
        block = ft_mem_qrealloc( memory, item_size,
                                 cur_count, new_count, block, &error );
        if ( !error && new_count > cur_count )
          FT_MEM_ZERO( (char*)block + cur_count * item_size,
                       ( new_count - cur_count ) * item_size );
    
        *p_error = error;
        return block;
      }
    
    
      FT_BASE_DEF( FT_Pointer )
      ft_mem_qrealloc( FT_Memory  memory,
                       FT_Long    item_size,
                       FT_Long    cur_count,
                       FT_Long    new_count,
                       void*      block,
                       FT_Error  *p_error )
      {
        FT_Error  error = FT_Err_Ok;
    
    
        /* Note that we now accept `item_size == 0' as a valid parameter, in
         * order to cover very weird cases where an ALLOC_MULT macro would be
         * called.
         */
        if ( cur_count < 0 || new_count < 0 || item_size < 0 )
        {
          /* may help catch/prevent nasty security issues */
          error = FT_Err_Invalid_Argument;
        }
        else if ( new_count == 0 || item_size == 0 )
        {
          ft_mem_free( memory, block );
          block = NULL;
        }
        else if ( new_count > FT_INT_MAX/item_size )
        {
          error = FT_Err_Array_Too_Large;
        }
        else if ( cur_count == 0 )
        {
          FT_ASSERT( block == NULL );
    
          block = ft_mem_alloc( memory, new_count*item_size, &error );
        }
        else
        {
          FT_Pointer  block2;
          FT_Long     cur_size = cur_count*item_size;
          FT_Long     new_size = new_count*item_size;
    
    
          block2 = memory->realloc( memory, cur_size, new_size, block );
          if ( block2 == NULL )
            error = FT_Err_Out_Of_Memory;
          else
            block = block2;
        }
    
        *p_error = error;
        return block;
      }
    
    
      FT_BASE_DEF( void )
      ft_mem_free( FT_Memory   memory,
                   const void *P )
      {
        if ( P )
          memory->free( memory, (void*)P );
      }
    
    
      /*************************************************************************/
      /*************************************************************************/
      /*************************************************************************/
      /*****                                                               *****/
      /*****                                                               *****/
      /*****            D O U B L Y   L I N K E D   L I S T S              *****/
      /*****                                                               *****/
      /*****                                                               *****/
      /*************************************************************************/
      /*************************************************************************/
      /*************************************************************************/
    
    #undef  FT_COMPONENT
    #define FT_COMPONENT  trace_list
    
      /* documentation is in ftlist.h */
    
      FT_EXPORT_DEF( FT_ListNode )
      FT_List_Find( FT_List  list,
                    void*    data )
      {
        FT_ListNode  cur;
    
    
        cur = list->head;
        while ( cur )
        {
          if ( cur->data == data )
            return cur;
    
          cur = cur->next;
        }
    
        return (FT_ListNode)0;
      }
    
    
      /* documentation is in ftlist.h */
    
      FT_EXPORT_DEF( void )
      FT_List_Add( FT_List      list,
                   FT_ListNode  node )
      {
        FT_ListNode  before = list->tail;
    
    
        node->next = 0;
        node->prev = before;
    
        if ( before )
          before->next = node;
        else
          list->head = node;
    
        list->tail = node;
      }
    
    
      /* documentation is in ftlist.h */
    
      FT_EXPORT_DEF( void )
      FT_List_Insert( FT_List      list,
                      FT_ListNode  node )
      {
        FT_ListNode  after = list->head;
    
    
        node->next = after;
        node->prev = 0;
    
        if ( !after )
          list->tail = node;
        else
          after->prev = node;
    
        list->head = node;
      }
    
    
      /* documentation is in ftlist.h */
    
      FT_EXPORT_DEF( void )
      FT_List_Remove( FT_List      list,
                      FT_ListNode  node )
      {
        FT_ListNode  before, after;
    
    
        before = node->prev;
        after  = node->next;
    
        if ( before )
          before->next = after;
        else
          list->head = after;
    
        if ( after )
          after->prev = before;
        else
          list->tail = before;
      }
    
    
      /* documentation is in ftlist.h */
    
      FT_EXPORT_DEF( void )
      FT_List_Up( FT_List      list,
                  FT_ListNode  node )
      {
        FT_ListNode  before, after;
    
    
        before = node->prev;
        after  = node->next;
    
        /* check whether we are already on top of the list */
        if ( !before )
          return;
    
        before->next = after;
    
        if ( after )
          after->prev = before;
        else
          list->tail = before;
    
        node->prev       = 0;
        node->next       = list->head;
        list->head->prev = node;
        list->head       = node;
      }
    
    
      /* documentation is in ftlist.h */
    
      FT_EXPORT_DEF( FT_Error )
      FT_List_Iterate( FT_List            list,
                       FT_List_Iterator   iterator,
                       void*              user )
      {
        FT_ListNode  cur   = list->head;
        FT_Error     error = FT_Err_Ok;
    
    
        while ( cur )
        {
          FT_ListNode  next = cur->next;
    
    
          error = iterator( cur, user );
          if ( error )
            break;
    
          cur = next;
        }
    
        return error;
      }
    
    
      /* documentation is in ftlist.h */
    
      FT_EXPORT_DEF( void )
      FT_List_Finalize( FT_List             list,
                        FT_List_Destructor  destroy,
                        FT_Memory           memory,
                        void*               user )
      {
        FT_ListNode  cur;
    
    
        cur = list->head;
        while ( cur )
        {
          FT_ListNode  next = cur->next;
          void*        data = cur->data;
    
    
          if ( destroy )
            destroy( memory, data, user );
    
          FT_FREE( cur );
          cur = next;
        }
    
        list->head = 0;
        list->tail = 0;
      }
    
    
      FT_BASE_DEF( FT_UInt32 )
      ft_highpow2( FT_UInt32  value )
      {
        FT_UInt32  value2;
    
    
        /*
         *  We simply clear the lowest bit in each iteration.  When
         *  we reach 0, we know that the previous value was our result.
         */
        for ( ;; )
        {
          value2 = value & (value - 1);  /* clear lowest bit */
          if ( value2 == 0 )
            break;
    
          value = value2;
        }
        return value;
      }
    
    
    #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
    
      FT_BASE_DEF( FT_Error )
      FT_Alloc( FT_Memory  memory,
                FT_Long    size,
                void*     *P )
      {
        FT_Error  error;
    
    
        (void)FT_ALLOC( *P, size );
        return error;
      }
    
    
      FT_BASE_DEF( FT_Error )
      FT_QAlloc( FT_Memory  memory,
                 FT_Long    size,
                 void*     *p )
      {
        FT_Error  error;
    
    
        (void)FT_QALLOC( *p, size );
        return error;
      }
    
    
      FT_BASE_DEF( FT_Error )
      FT_Realloc( FT_Memory  memory,
                  FT_Long    current,
                  FT_Long    size,
                  void*     *P )
      {
        FT_Error  error;
    
    
        (void)FT_REALLOC( *P, current, size );
        return error;
      }
    
    
      FT_BASE_DEF( FT_Error )
      FT_QRealloc( FT_Memory  memory,
                   FT_Long    current,
                   FT_Long    size,
                   void*     *p )
      {
        FT_Error  error;
    
    
        (void)FT_QREALLOC( *p, current, size );
        return error;
      }
    
    
      FT_BASE_DEF( void )
      FT_Free( FT_Memory  memory,
               void*     *P )
      {
        if ( *P )
          FT_MEM_FREE( *P );
      }
    
    #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
    
    /* END */