(root)/
freetype-2.13.2/
src/
psaux/
psarrst.c
       1  /****************************************************************************
       2   *
       3   * psarrst.c
       4   *
       5   *   Adobe's code for Array Stacks (body).
       6   *
       7   * Copyright 2007-2013 Adobe Systems Incorporated.
       8   *
       9   * This software, and all works of authorship, whether in source or
      10   * object code form as indicated by the copyright notice(s) included
      11   * herein (collectively, the "Work") is made available, and may only be
      12   * used, modified, and distributed under the FreeType Project License,
      13   * LICENSE.TXT.  Additionally, subject to the terms and conditions of the
      14   * FreeType Project License, each contributor to the Work hereby grants
      15   * to any individual or legal entity exercising permissions granted by
      16   * the FreeType Project License and this section (hereafter, "You" or
      17   * "Your") a perpetual, worldwide, non-exclusive, no-charge,
      18   * royalty-free, irrevocable (except as stated in this section) patent
      19   * license to make, have made, use, offer to sell, sell, import, and
      20   * otherwise transfer the Work, where such license applies only to those
      21   * patent claims licensable by such contributor that are necessarily
      22   * infringed by their contribution(s) alone or by combination of their
      23   * contribution(s) with the Work to which such contribution(s) was
      24   * submitted.  If You institute patent litigation against any entity
      25   * (including a cross-claim or counterclaim in a lawsuit) alleging that
      26   * the Work or a contribution incorporated within the Work constitutes
      27   * direct or contributory patent infringement, then any patent licenses
      28   * granted to You under this License for that Work shall terminate as of
      29   * the date such litigation is filed.
      30   *
      31   * By using, modifying, or distributing the Work you indicate that you
      32   * have read and understood the terms and conditions of the
      33   * FreeType Project License as well as those provided in this section,
      34   * and you accept them fully.
      35   *
      36   */
      37  
      38  
      39  #include "psft.h"
      40  #include <freetype/internal/ftdebug.h>
      41  
      42  #include "psglue.h"
      43  #include "psarrst.h"
      44  
      45  #include "pserror.h"
      46  
      47  
      48    /*
      49     * CF2_ArrStack uses an error pointer, to enable shared errors.
      50     * Shared errors are necessary when multiple objects allow the program
      51     * to continue after detecting errors.  Only the first error should be
      52     * recorded.
      53     */
      54  
      55    FT_LOCAL_DEF( void )
      56    cf2_arrstack_init( CF2_ArrStack  arrstack,
      57                       FT_Memory     memory,
      58                       FT_Error*     error,
      59                       size_t        sizeItem )
      60    {
      61      FT_ASSERT( arrstack );
      62  
      63      /* initialize the structure */
      64      arrstack->memory    = memory;
      65      arrstack->error     = error;
      66      arrstack->sizeItem  = sizeItem;
      67      arrstack->allocated = 0;
      68      arrstack->count     = 0;
      69      arrstack->totalSize = 0;
      70      arrstack->ptr       = NULL;
      71    }
      72  
      73  
      74    FT_LOCAL_DEF( void )
      75    cf2_arrstack_finalize( CF2_ArrStack  arrstack )
      76    {
      77      FT_Memory  memory = arrstack->memory;     /* for FT_FREE */
      78  
      79  
      80      FT_ASSERT( arrstack );
      81  
      82      arrstack->allocated = 0;
      83      arrstack->count     = 0;
      84      arrstack->totalSize = 0;
      85  
      86      /* free the data buffer */
      87      FT_FREE( arrstack->ptr );
      88    }
      89  
      90  
      91    /* allocate or reallocate the buffer size; */
      92    /* return false on memory error */
      93    static FT_Bool
      94    cf2_arrstack_setNumElements( CF2_ArrStack  arrstack,
      95                                 size_t        numElements )
      96    {
      97      FT_ASSERT( arrstack );
      98  
      99      {
     100        FT_Error   error  = FT_Err_Ok;        /* for FT_REALLOC */
     101        FT_Memory  memory = arrstack->memory; /* for FT_REALLOC */
     102  
     103        size_t  newSize = numElements * arrstack->sizeItem;
     104  
     105  
     106        if ( numElements > FT_LONG_MAX / arrstack->sizeItem )
     107          goto exit;
     108  
     109  
     110        FT_ASSERT( newSize > 0 );   /* avoid realloc with zero size */
     111  
     112        if ( !FT_QREALLOC( arrstack->ptr, arrstack->totalSize, newSize ) )
     113        {
     114          arrstack->allocated = numElements;
     115          arrstack->totalSize = newSize;
     116  
     117          if ( arrstack->count > numElements )
     118          {
     119            /* we truncated the list! */
     120            CF2_SET_ERROR( arrstack->error, Stack_Overflow );
     121            arrstack->count = numElements;
     122            return FALSE;
     123          }
     124  
     125          return TRUE;     /* success */
     126        }
     127      }
     128  
     129    exit:
     130      /* if there's not already an error, store this one */
     131      CF2_SET_ERROR( arrstack->error, Out_Of_Memory );
     132  
     133      return FALSE;
     134    }
     135  
     136  
     137    /* set the count, ensuring allocation is sufficient */
     138    FT_LOCAL_DEF( void )
     139    cf2_arrstack_setCount( CF2_ArrStack  arrstack,
     140                           size_t        numElements )
     141    {
     142      FT_ASSERT( arrstack );
     143  
     144      if ( numElements > arrstack->allocated )
     145      {
     146        /* expand the allocation first */
     147        if ( !cf2_arrstack_setNumElements( arrstack, numElements ) )
     148          return;
     149      }
     150  
     151      arrstack->count = numElements;
     152    }
     153  
     154  
     155    /* clear the count */
     156    FT_LOCAL_DEF( void )
     157    cf2_arrstack_clear( CF2_ArrStack  arrstack )
     158    {
     159      FT_ASSERT( arrstack );
     160  
     161      arrstack->count = 0;
     162    }
     163  
     164  
     165    /* current number of items */
     166    FT_LOCAL_DEF( size_t )
     167    cf2_arrstack_size( const CF2_ArrStack  arrstack )
     168    {
     169      FT_ASSERT( arrstack );
     170  
     171      return arrstack->count;
     172    }
     173  
     174  
     175    FT_LOCAL_DEF( void* )
     176    cf2_arrstack_getBuffer( const CF2_ArrStack  arrstack )
     177    {
     178      FT_ASSERT( arrstack );
     179  
     180      return arrstack->ptr;
     181    }
     182  
     183  
     184    /* return pointer to the given element */
     185    FT_LOCAL_DEF( void* )
     186    cf2_arrstack_getPointer( const CF2_ArrStack  arrstack,
     187                             size_t              idx )
     188    {
     189      void*  newPtr;
     190  
     191  
     192      FT_ASSERT( arrstack );
     193  
     194      if ( idx >= arrstack->count )
     195      {
     196        /* overflow */
     197        CF2_SET_ERROR( arrstack->error, Stack_Overflow );
     198        idx = 0;    /* choose safe default */
     199      }
     200  
     201      newPtr = (FT_Byte*)arrstack->ptr + idx * arrstack->sizeItem;
     202  
     203      return newPtr;
     204    }
     205  
     206  
     207    /* push (append) an element at the end of the list;         */
     208    /* return false on memory error                             */
     209    /* TODO: should there be a length param for extra checking? */
     210    FT_LOCAL_DEF( void )
     211    cf2_arrstack_push( CF2_ArrStack  arrstack,
     212                       const void*   ptr )
     213    {
     214      FT_ASSERT( arrstack );
     215  
     216      if ( arrstack->count == arrstack->allocated )
     217      {
     218        /* increase the buffer size */
     219        if ( !cf2_arrstack_setNumElements(
     220               arrstack, arrstack->allocated * 2 + 16 ) )
     221        {
     222          /* on error, ignore the push */
     223          return;
     224        }
     225      }
     226  
     227      FT_ASSERT( ptr );
     228  
     229      {
     230        size_t  offset = arrstack->count * arrstack->sizeItem;
     231        void*   newPtr = (FT_Byte*)arrstack->ptr + offset;
     232  
     233  
     234        FT_MEM_COPY( newPtr, ptr, arrstack->sizeItem );
     235        arrstack->count += 1;
     236      }
     237    }
     238  
     239  
     240  /* END */