home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / compiler / aros / freestruct.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-07  |  4.0 KB  |  202 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: freestruct.c,v 1.5 1997/02/07 14:22:37 digulla Exp $
  4.  
  5.     Desc: Free a structure returned by ReadStruct()
  6.     Lang: english
  7. */
  8. #define AROS_ALMOST_COMPATIBLE
  9. #include <string.h>
  10. #include <exec/memory.h>
  11. #include <proto/dos.h>
  12. #include <proto/exec.h>
  13. #include <aros/debug.h>
  14. #include <utility/hooks.h>
  15.  
  16. struct FreeLevel
  17. {
  18.     struct MinNode   node;
  19.     const IPTR       * sd;
  20.     UBYTE       * s;
  21.     ULONG         size;
  22.     int          pos;
  23. };
  24.  
  25. /******************************************************************************
  26.  
  27.     NAME */
  28. #include <stdio.h>
  29. #include <aros/structdesc.h>
  30. #include <proto/alib.h>
  31.  
  32.     void FreeStruct (
  33.  
  34. /*  SYNOPSIS */
  35.     APTR         data,
  36.     const IPTR * sd)
  37.  
  38. /*  FUNCTION
  39.     Free a structure which was created by ReadStruct().
  40.  
  41.     INPUTS
  42.     data - This was returned by ReadStruct() in the dataptr parameter.
  43.         Must be non-NULL.
  44.     sd - Description of the structure to be read. The first element
  45.         is the size of the structure.
  46.  
  47.     RESULT
  48.     None.
  49.  
  50.     NOTES
  51.  
  52.     EXAMPLE
  53.     See ReadStruct()
  54.  
  55.     BUGS
  56.  
  57.     SEE ALSO
  58.     Open(), Close(), ReadByte(), ReadWord(), ReadLong(), ReadFloat(),
  59.     ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(),
  60.     WriteFloat(), WriteDouble(), WriteString(), WriteStruct()
  61.  
  62.     HISTORY
  63.     29.11.96    ada created
  64.  
  65. ******************************************************************************/
  66. {
  67.     struct MinList     _list;
  68.     struct FreeLevel * curr;
  69.  
  70. #   define list     ((struct List *)&_list)
  71.  
  72.     NEWLIST(list);
  73.  
  74.     if (!(curr = AllocMem (sizeof (struct FreeLevel), MEMF_ANY)) )
  75.     return;
  76.  
  77.     AddTail (list, (struct Node *)curr);
  78.  
  79.     curr->sd  = sd;
  80.     curr->pos = 0;
  81.     curr->s   = data;
  82.  
  83. #   define DESC     curr->sd[curr->pos]
  84. #   define IDESC    curr->sd[curr->pos ++]
  85.  
  86.     for (;;)
  87.     {
  88.     if (!curr->pos)
  89.     {
  90.         curr->size = IDESC;
  91.     }
  92.  
  93.     if (DESC == SDT_END)
  94.         break;
  95.  
  96.     switch (IDESC)
  97.     {
  98.     case SDT_UBYTE:      /* Read one  8bit byte */
  99.     case SDT_UWORD:      /* Read one 16bit word */
  100.     case SDT_ULONG:      /* Read one 32bit long */
  101.     case SDT_FLOAT:      /* Read one 32bit IEEE */
  102.     case SDT_DOUBLE:     /* Read one 64bit IEEE */
  103.     case SDT_IGNORE:     /* Ignore x bytes */
  104.         /* Ignore these */
  105.         curr->pos ++;
  106.         break;
  107.  
  108.     case SDT_STRING: {   /* Read a string */
  109.         STRPTR sptr;
  110.  
  111.         sptr = *(STRPTR *)(curr->s + IDESC);
  112.  
  113.         if (sptr)
  114.         FreeVec (sptr);
  115.  
  116.         break; }
  117.  
  118.     case SDT_STRUCT: {    /* Read a structure */
  119.         /* Ignore two parameters */
  120.         curr->pos += 2;
  121.  
  122.         break; }
  123.  
  124.     case SDT_PTR: {    /* Follow a pointer */
  125.         struct FreeLevel * next;
  126.  
  127.         IPTR * desc;
  128.         APTR * aptr;
  129.  
  130.         aptr = ((APTR *)(curr->s + IDESC));
  131.         desc = (IPTR *)IDESC;
  132.  
  133.         if (*aptr)
  134.         {
  135.         if (!(next = AllocMem (sizeof (struct FreeLevel), MEMF_ANY)) )
  136.             goto error;
  137.  
  138.         AddTail (list, (struct Node *)next);
  139.         next->sd  = desc;
  140.         next->pos = 0;
  141.         next->s   = *aptr;
  142.  
  143.         curr = next;
  144.         }
  145.  
  146.         break; }
  147.  
  148.     case SDT_FILL_BYTE:   /* Fill x bytes */
  149.     case SDT_FILL_LONG:   /* Fill x longs */
  150.     case SDT_IFILL_BYTE:  /* Fill x bytes */
  151.     case SDT_IFILL_LONG:  /* Fill x longs */
  152.         curr->pos += 3; /* Ignore three parameters */
  153.         break;
  154.  
  155.     case SDT_SPECIAL: {   /* Call user hook */
  156.         struct Hook * hook;
  157.         struct SDData data;
  158.  
  159.         data.sdd_Dest = ((APTR)(curr->s + IDESC));
  160.         data.sdd_Mode = SDV_SPECIALMODE_FREE;
  161.  
  162.         hook = (struct Hook *)IDESC;
  163.  
  164.         CallHookA (hook, NULL, &data);
  165.  
  166.         break; }
  167.  
  168.     } /* switch */
  169.  
  170.     /* End of the description list ? */
  171.     if (DESC == SDT_END)
  172.     {
  173.         struct FreeLevel * last;
  174.  
  175.         /* Remove the current level */
  176.         last = curr;
  177.         Remove ((struct Node *)last);
  178.  
  179.         /* Get the last level */
  180.         if ((curr = GetTail (list)))
  181.         {
  182.         FreeMem (last->s, last->size);
  183.         FreeMem (last, sizeof (struct FreeLevel));
  184.         }
  185.         else
  186.         {
  187.         curr = last;
  188.         }
  189.     }
  190.     } /* while */
  191.  
  192.     FreeMem (curr->s, curr->size);
  193.     FreeMem (curr, sizeof (struct FreeLevel));
  194.  
  195.     return;
  196.  
  197. error:
  198.     while ((curr = (struct FreeLevel *)RemTail (list)))
  199.     FreeMem (curr, sizeof (struct FreeLevel));
  200. } /* FreeStruct */
  201.  
  202.