Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ftutil.c                                                               */
  4. /*                                                                         */
  5. /*    FreeType utility file for memory and list management (body).         */
  6. /*                                                                         */
  7. /*  Copyright 2002, 2004-2007, 2013 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_THROW( Out_Of_Memory );
  79.     }
  80.     else if ( size < 0 )
  81.     {
  82.       /* may help catch/prevent security issues */
  83.       error = FT_THROW( 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.  
  102.     block = ft_mem_qrealloc( memory, item_size,
  103.                              cur_count, new_count, block, &error );
  104.     if ( !error && new_count > cur_count )
  105.       FT_MEM_ZERO( (char*)block + cur_count * item_size,
  106.                    ( new_count - cur_count ) * item_size );
  107.  
  108.     *p_error = error;
  109.     return block;
  110.   }
  111.  
  112.  
  113.   FT_BASE_DEF( FT_Pointer )
  114.   ft_mem_qrealloc( FT_Memory  memory,
  115.                    FT_Long    item_size,
  116.                    FT_Long    cur_count,
  117.                    FT_Long    new_count,
  118.                    void*      block,
  119.                    FT_Error  *p_error )
  120.   {
  121.     FT_Error  error = FT_Err_Ok;
  122.  
  123.  
  124.     /* Note that we now accept `item_size == 0' as a valid parameter, in
  125.      * order to cover very weird cases where an ALLOC_MULT macro would be
  126.      * called.
  127.      */
  128.     if ( cur_count < 0 || new_count < 0 || item_size < 0 )
  129.     {
  130.       /* may help catch/prevent nasty security issues */
  131.       error = FT_THROW( Invalid_Argument );
  132.     }
  133.     else if ( new_count == 0 || item_size == 0 )
  134.     {
  135.       ft_mem_free( memory, block );
  136.       block = NULL;
  137.     }
  138.     else if ( new_count > FT_INT_MAX/item_size )
  139.     {
  140.       error = FT_THROW( Array_Too_Large );
  141.     }
  142.     else if ( cur_count == 0 )
  143.     {
  144.       FT_ASSERT( block == NULL );
  145.  
  146.       block = ft_mem_alloc( memory, new_count*item_size, &error );
  147.     }
  148.     else
  149.     {
  150.       FT_Pointer  block2;
  151.       FT_Long     cur_size = cur_count*item_size;
  152.       FT_Long     new_size = new_count*item_size;
  153.  
  154.  
  155.       block2 = memory->realloc( memory, cur_size, new_size, block );
  156.       if ( block2 == NULL )
  157.         error = FT_THROW( Out_Of_Memory );
  158.       else
  159.         block = block2;
  160.     }
  161.  
  162.     *p_error = error;
  163.     return block;
  164.   }
  165.  
  166.  
  167.   FT_BASE_DEF( void )
  168.   ft_mem_free( FT_Memory   memory,
  169.                const void *P )
  170.   {
  171.     if ( P )
  172.       memory->free( memory, (void*)P );
  173.   }
  174.  
  175.  
  176.   FT_BASE_DEF( FT_Pointer )
  177.   ft_mem_dup( FT_Memory    memory,
  178.               const void*  address,
  179.               FT_ULong     size,
  180.               FT_Error    *p_error )
  181.   {
  182.     FT_Error    error;
  183.     FT_Pointer  p = ft_mem_qalloc( memory, size, &error );
  184.  
  185.  
  186.     if ( !error && address )
  187.       ft_memcpy( p, address, size );
  188.  
  189.     *p_error = error;
  190.     return p;
  191.   }
  192.  
  193.  
  194.   FT_BASE_DEF( FT_Pointer )
  195.   ft_mem_strdup( FT_Memory    memory,
  196.                  const char*  str,
  197.                  FT_Error    *p_error )
  198.   {
  199.     FT_ULong  len = str ? (FT_ULong)ft_strlen( str ) + 1
  200.                         : 0;
  201.  
  202.  
  203.     return ft_mem_dup( memory, str, len, p_error );
  204.   }
  205.  
  206.  
  207.   FT_BASE_DEF( FT_Int )
  208.   ft_mem_strcpyn( char*        dst,
  209.                   const char*  src,
  210.                   FT_ULong     size )
  211.   {
  212.     while ( size > 1 && *src != 0 )
  213.     {
  214.       *dst++ = *src++;
  215.       size--;
  216.     }
  217.  
  218.     *dst = 0;  /* always zero-terminate */
  219.  
  220.     return *src != 0;
  221.   }
  222.  
  223.  
  224.   /*************************************************************************/
  225.   /*************************************************************************/
  226.   /*************************************************************************/
  227.   /*****                                                               *****/
  228.   /*****                                                               *****/
  229.   /*****            D O U B L Y   L I N K E D   L I S T S              *****/
  230.   /*****                                                               *****/
  231.   /*****                                                               *****/
  232.   /*************************************************************************/
  233.   /*************************************************************************/
  234.   /*************************************************************************/
  235.  
  236. #undef  FT_COMPONENT
  237. #define FT_COMPONENT  trace_list
  238.  
  239.   /* documentation is in ftlist.h */
  240.  
  241.   FT_EXPORT_DEF( FT_ListNode )
  242.   FT_List_Find( FT_List  list,
  243.                 void*    data )
  244.   {
  245.     FT_ListNode  cur;
  246.  
  247.  
  248.     cur = list->head;
  249.     while ( cur )
  250.     {
  251.       if ( cur->data == data )
  252.         return cur;
  253.  
  254.       cur = cur->next;
  255.     }
  256.  
  257.     return (FT_ListNode)0;
  258.   }
  259.  
  260.  
  261.   /* documentation is in ftlist.h */
  262.  
  263.   FT_EXPORT_DEF( void )
  264.   FT_List_Add( FT_List      list,
  265.                FT_ListNode  node )
  266.   {
  267.     FT_ListNode  before = list->tail;
  268.  
  269.  
  270.     node->next = 0;
  271.     node->prev = before;
  272.  
  273.     if ( before )
  274.       before->next = node;
  275.     else
  276.       list->head = node;
  277.  
  278.     list->tail = node;
  279.   }
  280.  
  281.  
  282.   /* documentation is in ftlist.h */
  283.  
  284.   FT_EXPORT_DEF( void )
  285.   FT_List_Insert( FT_List      list,
  286.                   FT_ListNode  node )
  287.   {
  288.     FT_ListNode  after = list->head;
  289.  
  290.  
  291.     node->next = after;
  292.     node->prev = 0;
  293.  
  294.     if ( !after )
  295.       list->tail = node;
  296.     else
  297.       after->prev = node;
  298.  
  299.     list->head = node;
  300.   }
  301.  
  302.  
  303.   /* documentation is in ftlist.h */
  304.  
  305.   FT_EXPORT_DEF( void )
  306.   FT_List_Remove( FT_List      list,
  307.                   FT_ListNode  node )
  308.   {
  309.     FT_ListNode  before, after;
  310.  
  311.  
  312.     before = node->prev;
  313.     after  = node->next;
  314.  
  315.     if ( before )
  316.       before->next = after;
  317.     else
  318.       list->head = after;
  319.  
  320.     if ( after )
  321.       after->prev = before;
  322.     else
  323.       list->tail = before;
  324.   }
  325.  
  326.  
  327.   /* documentation is in ftlist.h */
  328.  
  329.   FT_EXPORT_DEF( void )
  330.   FT_List_Up( FT_List      list,
  331.               FT_ListNode  node )
  332.   {
  333.     FT_ListNode  before, after;
  334.  
  335.  
  336.     before = node->prev;
  337.     after  = node->next;
  338.  
  339.     /* check whether we are already on top of the list */
  340.     if ( !before )
  341.       return;
  342.  
  343.     before->next = after;
  344.  
  345.     if ( after )
  346.       after->prev = before;
  347.     else
  348.       list->tail = before;
  349.  
  350.     node->prev       = 0;
  351.     node->next       = list->head;
  352.     list->head->prev = node;
  353.     list->head       = node;
  354.   }
  355.  
  356.  
  357.   /* documentation is in ftlist.h */
  358.  
  359.   FT_EXPORT_DEF( FT_Error )
  360.   FT_List_Iterate( FT_List            list,
  361.                    FT_List_Iterator   iterator,
  362.                    void*              user )
  363.   {
  364.     FT_ListNode  cur   = list->head;
  365.     FT_Error     error = FT_Err_Ok;
  366.  
  367.  
  368.     while ( cur )
  369.     {
  370.       FT_ListNode  next = cur->next;
  371.  
  372.  
  373.       error = iterator( cur, user );
  374.       if ( error )
  375.         break;
  376.  
  377.       cur = next;
  378.     }
  379.  
  380.     return error;
  381.   }
  382.  
  383.  
  384.   /* documentation is in ftlist.h */
  385.  
  386.   FT_EXPORT_DEF( void )
  387.   FT_List_Finalize( FT_List             list,
  388.                     FT_List_Destructor  destroy,
  389.                     FT_Memory           memory,
  390.                     void*               user )
  391.   {
  392.     FT_ListNode  cur;
  393.  
  394.  
  395.     cur = list->head;
  396.     while ( cur )
  397.     {
  398.       FT_ListNode  next = cur->next;
  399.       void*        data = cur->data;
  400.  
  401.  
  402.       if ( destroy )
  403.         destroy( memory, data, user );
  404.  
  405.       FT_FREE( cur );
  406.       cur = next;
  407.     }
  408.  
  409.     list->head = 0;
  410.     list->tail = 0;
  411.   }
  412.  
  413.  
  414.   FT_BASE_DEF( FT_UInt32 )
  415.   ft_highpow2( FT_UInt32  value )
  416.   {
  417.     FT_UInt32  value2;
  418.  
  419.  
  420.     /*
  421.      *  We simply clear the lowest bit in each iteration.  When
  422.      *  we reach 0, we know that the previous value was our result.
  423.      */
  424.     for ( ;; )
  425.     {
  426.       value2 = value & (value - 1);  /* clear lowest bit */
  427.       if ( value2 == 0 )
  428.         break;
  429.  
  430.       value = value2;
  431.     }
  432.     return value;
  433.   }
  434.  
  435.  
  436. /* END */
  437.