tabs->spaces
[AROS.git] / compiler / arossupport / freestruct.c
blob7e31c9d5c4bdbd6161fa3cfcb6d59dd66f640c56
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Free a structure returned by ReadStruct()
6 Lang: english
7 */
9 #include <exec/memory.h>
10 #include <proto/dos.h>
11 #include <proto/exec.h>
12 #include <aros/debug.h>
13 #include <utility/hooks.h>
15 struct FreeLevel
17 struct MinNode node;
18 const IPTR * sd;
19 UBYTE * s;
20 ULONG size;
21 int pos;
24 /******************************************************************************
26 NAME */
27 #include <stdio.h>
28 #include <aros/bigendianio.h>
29 #include <proto/alib.h>
31 void FreeStruct (
33 /* SYNOPSIS */
34 APTR data,
35 const IPTR * sd)
37 /* FUNCTION
38 Free a structure which was created by ReadStruct().
40 INPUTS
41 data - This was returned by ReadStruct() in the dataptr parameter.
42 Must be non-NULL.
43 sd - Description of the structure to be read. The first element
44 is the size of the structure.
46 RESULT
47 None.
49 NOTES
51 EXAMPLE
52 See ReadStruct()
54 BUGS
56 SEE ALSO
57 dos.library/Open(), dos.library/Close(), ReadByte(), ReadWord(),
58 ReadLong(), ReadFloat(),
59 ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(),
60 WriteFloat(), WriteDouble(), WriteString(), WriteStruct()
62 ******************************************************************************/
64 struct MinList _list;
65 struct FreeLevel * curr;
67 # define list ((struct List *)&_list)
69 NEWLIST(list);
71 if (!(curr = AllocMem (sizeof (struct FreeLevel), MEMF_ANY)) )
72 return;
74 AddTail (list, (struct Node *)curr);
76 curr->sd = sd;
77 curr->pos = 0;
78 curr->s = data;
80 # define DESC curr->sd[curr->pos]
81 # define IDESC curr->sd[curr->pos ++]
83 for (;;)
85 if (!curr->pos)
87 curr->size = IDESC;
90 if (DESC == SDT_END)
91 break;
93 switch (IDESC)
95 case SDT_UBYTE: /* Read one 8bit byte */
96 case SDT_UWORD: /* Read one 16bit word */
97 case SDT_ULONG: /* Read one 32bit long */
98 case SDT_FLOAT: /* Read one 32bit IEEE */
99 case SDT_DOUBLE: /* Read one 64bit IEEE */
100 case SDT_IGNORE: /* Ignore x bytes */
101 /* Ignore these */
102 curr->pos ++;
103 break;
105 case SDT_STRING: { /* Read a string */
106 STRPTR sptr;
108 sptr = *(STRPTR *)(curr->s + IDESC);
110 FreeVec (sptr);
112 break; }
114 case SDT_STRUCT: { /* Read a structure */
115 /* Ignore two parameters */
116 curr->pos += 2;
118 break; }
120 case SDT_PTR: { /* Follow a pointer */
121 struct FreeLevel * next;
123 IPTR * desc;
124 APTR * aptr;
126 aptr = ((APTR *)(curr->s + IDESC));
127 desc = (IPTR *)IDESC;
129 if (*aptr)
131 if (!(next = AllocMem (sizeof (struct FreeLevel), MEMF_ANY)) )
132 goto error;
134 AddTail (list, (struct Node *)next);
135 next->sd = desc;
136 next->pos = 0;
137 next->s = *aptr;
139 curr = next;
142 break; }
144 case SDT_FILL_BYTE: /* Fill x bytes */
145 case SDT_FILL_LONG: /* Fill x longs */
146 case SDT_IFILL_BYTE: /* Fill x bytes */
147 case SDT_IFILL_LONG: /* Fill x longs */
148 curr->pos += 3; /* Ignore three parameters */
149 break;
151 case SDT_SPECIAL: { /* Call user hook */
152 struct Hook * hook;
153 struct SDData data;
155 data.sdd_Dest = ((APTR)(curr->s + IDESC));
156 data.sdd_Mode = SDV_SPECIALMODE_FREE;
158 hook = (struct Hook *)IDESC;
160 CallHookA (hook, NULL, &data);
162 break; }
164 } /* switch */
166 /* End of the description list ? */
167 if (DESC == SDT_END)
169 struct FreeLevel * last;
171 /* Remove the current level */
172 last = curr;
173 Remove ((struct Node *)last);
175 /* Get the last level */
176 if ((curr = (struct FreeLevel *)GetTail (list)))
178 FreeMem (last->s, last->size);
179 FreeMem (last, sizeof (struct FreeLevel));
181 else
183 curr = last;
186 } /* while */
188 FreeMem (curr->s, curr->size);
189 FreeMem (curr, sizeof (struct FreeLevel));
191 return;
193 error:
194 while ((curr = (struct FreeLevel *)RemTail (list)))
195 FreeMem (curr, sizeof (struct FreeLevel));
196 } /* FreeStruct */