home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / ft-beta.zip / freetype / lib / ttlists.c < prev    next >
C/C++ Source or Header  |  1997-10-06  |  8KB  |  301 lines

  1. /*******************************************************************
  2.  *
  3.  *  ttlists.c                                                   1.0
  4.  *
  5.  *    Generic lists routines.
  6.  *
  7.  *  Copyright 1996, 1997 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.  *  IMPORTANT NOTE :
  17.  *
  18.  *    These routines should only be used within managers. As a
  19.  *    consequence, they do not provide support for thread-safety
  20.  *    or re-entrancy.
  21.  *
  22.  ******************************************************************/
  23.  
  24. #include "ttengine.h"
  25. #include "ttlists.h"
  26. #include "tterror.h"
  27. #include "ttmutex.h"
  28. #include "ttmemory.h"
  29.  
  30.   #define FREE_Elements  engine.list_free_elements
  31.   /* The macro FREE_Elements aliases the current engine instance's */
  32.   /* free list_elements recycle list                               */
  33.   
  34.   #define LOCK()    MUTEX_Lock   ( engine.lock )
  35.   #define UNLOCK()  MUTEX_Release( engine.lock )
  36.  
  37. /*******************************************************************
  38.  *
  39.  *  Function    :  Element_New
  40.  *
  41.  *  Description :  gets a new ( either fresh or recycled ) list
  42.  *                 element. The element is unlisted.
  43.  *
  44.  *  Input  :  None
  45.  *
  46.  *  Output :  list element address. NULL if out of memory..
  47.  *
  48.  ******************************************************************/
  49.  
  50.   PList_Element  Element_New()
  51.   {
  52.     PList_Element  element;
  53.  
  54.     LOCK();
  55.  
  56.     if (FREE_Elements)
  57.     {
  58.       element       = (PList_Element)FREE_Elements;
  59.       FREE_Elements = element->next;
  60.     }
  61.     else
  62.     {
  63.       if ( !MEM_Alloc( element, sizeof(TList_Element)) )
  64.       {
  65.         element->next = NULL;
  66.         element->data = NULL;
  67.       }
  68.     }
  69.  
  70.     /* Note : in case of failure, Alloc set the pointer to NULL */
  71.  
  72.     UNLOCK();
  73.  
  74.     return element;
  75.   }
  76.  
  77.  
  78. /*******************************************************************
  79.  *
  80.  *  Function    :  Element_Done
  81.  *
  82.  *  Description :  recycles an unlinked list element.
  83.  *
  84.  *  Input  :  the list element to recycle. It _must_ be unlisted.
  85.  *
  86.  *  Output :  none.
  87.  *
  88.  *  Note   :    This function doesn't check the element
  89.  *
  90.  ******************************************************************/
  91.  
  92.   void Element_Done( PList_Element element )
  93.   {
  94.     LOCK();
  95.  
  96.     /* Simply add the list element to the recycle list */
  97.  
  98.     element->next = (PList_Element)FREE_Elements;
  99.     FREE_Elements = element;
  100.  
  101.     UNLOCK();
  102.   }
  103.  
  104.  
  105. /*******************************************************************
  106.  *
  107.  *  Function    :  List_Add
  108.  *
  109.  *  Description :  adds a new list element at the tail of a
  110.  *                 given list.
  111.  *
  112.  *  Input  :  list     the list
  113.  *            element  the element to add
  114.  *
  115.  ******************************************************************/
  116.  
  117.   void List_Add( TSingle_List*  list,
  118.                  PList_Element  element )
  119.   {
  120.     Assert( element, Panic( "TTLists.List_Add : void element" ));
  121.  
  122.     element->next = NULL;
  123.  
  124.     if ( !list->head )
  125.     {
  126.       Assert( list->tail, Panic( "TTLists.List_Add : incoherent list tail" ));
  127.       list->head = element;
  128.       list->tail = element;
  129.     }
  130.     else
  131.     {
  132.       Assert( !list->tail, Panic( "TTLists.List_Add : incoherent list head" ));
  133.       list->tail->next = element;
  134.       list->tail       = element;
  135.     }
  136.   }
  137.  
  138. /*******************************************************************
  139.  *
  140.  *  Function    :  List_Remove
  141.  *
  142.  *  Description :  remove an element from a given list. The
  143.  *                 element must be part of the list.
  144.  *
  145.  *  Input  :  list     the list
  146.  *            element  the element to remove
  147.  *
  148.  *  Output :  returns TRUE on success. FALSE on failure ( when
  149.  *            the element wasn't part of the list.. )
  150.  *
  151.  ******************************************************************/
  152.  
  153.   Bool List_Remove( TSingle_List*  list,
  154.                     PList_Element  element )
  155.   {
  156.     PList_Element  old, current;
  157.  
  158.     Assert( list && list->head && list->tail,
  159.             Panic( "TTLists.List_Remove : void or incoherent list" ));
  160.  
  161.     old     = NULL;
  162.     current = list->head;
  163.  
  164.     while (current)
  165.     {
  166.       if ( current == element )
  167.       {
  168.         if (old) 
  169.           old->next = current->next;
  170.         else
  171.           list->head = current->next;
  172.  
  173.         if (list->tail == current)
  174.           list->tail = old;
  175.  
  176.         return SUCCESS;
  177.       }
  178.  
  179.       old     = current;
  180.       current = current->next;
  181.     }
  182.  
  183.     return FAILURE;
  184.   }
  185.  
  186.  
  187. /*******************************************************************
  188.  *
  189.  *  Function    :  List_Find
  190.  *
  191.  *  Description :  find the first list element that matches
  192.  *                 the 'data' argument in a given list.
  193.  *
  194.  *  Input  :  list     the list
  195.  *            data     the data field to match
  196.  *
  197.  *  Output :  the found list element. NULL if none.              
  198.  *
  199.  ******************************************************************/
  200.  
  201.   PList_Element  List_Find( TSingle_List*  list,
  202.                             void*          data )
  203.   {
  204.     PList_Element  current;
  205.  
  206.     Assert( list, Panic( "TTLists.List_Find : invalid list" ));
  207.  
  208.     current = list->head;
  209.  
  210.     while (current)
  211.     {
  212.       if ( current->data==data )
  213.         return current;
  214.  
  215.       current = current->next;
  216.     }
  217.  
  218.     return NULL;
  219.   }
  220.  
  221. /*******************************************************************
  222.  *
  223.  *  Function    :  List_Extracts
  224.  *
  225.  *  Description :  extracts the first list element of a given
  226.  *                 list. This is useful for recycle lists.
  227.  *
  228.  *  Input  :  list     the list
  229.  *
  230.  *  Output :  the list element. Returns NULL if the list was  
  231.  *            empty                                  
  232.  *
  233.  ******************************************************************/
  234.  
  235.   PList_Element  List_Extract( TSingle_List*  list )
  236.   {
  237.     PList_Element  element;
  238.  
  239.     Assert( list, Panic( "TTLists.List_Extract : void list argument" ));
  240.  
  241.     element = list->head;
  242.  
  243.     if (element)
  244.     {
  245.       list->head = element->next;
  246.  
  247.       if ( list->tail==element )
  248.         list->tail = NULL;
  249.     }
  250.  
  251.     return element;
  252.   }
  253.  
  254. /*******************************************************************
  255.  *
  256.  *  Function    :  TTLists_Init
  257.  *
  258.  *  Description :  the component's initializer. Creates the  
  259.  *                 list mutex and inits the free list_elements
  260.  *                 list.
  261.  *
  262.  *  Input  :  engine instance
  263.  *
  264.  ******************************************************************/
  265.  
  266.   TT_Error  TTLists_Init()
  267.   {
  268.     /* init the free list_elements list */
  269.  
  270.     FREE_Elements = NULL;
  271.     return TT_Err_Ok;
  272.   }
  273.  
  274. /*******************************************************************
  275.  *
  276.  *  Function    :  TTLists_Done
  277.  *
  278.  *  Description :  the component's finalizer. Releases the   
  279.  *                 recycled list elements and destroys the mutex.
  280.  *
  281.  *  Input  :  engine instance for re-entrant builds only
  282.  *
  283.  ******************************************************************/
  284.  
  285.   TT_Error  TTLists_Done()
  286.   {
  287.     PList_Element element, next;
  288.  
  289.     /* frees the recycled list elements */
  290.  
  291.     element = FREE_Elements;
  292.     while (element)
  293.     {
  294.       next = element->next;
  295.       FREE( element );
  296.       element = next;
  297.     }
  298.     return TT_Err_Ok;
  299.   }
  300.  
  301.