Listtree.mcc: make Listtree inherit from List as it should
[AROS.git] / compiler / arossupport / freestruct.c
blob823467090c3be2d1d9aee82668673b8f5bcd0cec
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 <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>
16 struct FreeLevel
18 struct MinNode node;
19 const IPTR * sd;
20 UBYTE * s;
21 ULONG size;
22 int pos;
25 /******************************************************************************
27 NAME */
28 #include <stdio.h>
29 #include <aros/bigendianio.h>
30 #include <proto/alib.h>
32 void FreeStruct (
34 /* SYNOPSIS */
35 APTR data,
36 const IPTR * sd)
38 /* FUNCTION
39 Free a structure which was created by ReadStruct().
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.
47 RESULT
48 None.
50 NOTES
52 EXAMPLE
53 See ReadStruct()
55 BUGS
57 SEE ALSO
58 dos.library/Open(), dos.library/Close(), ReadByte(), ReadWord(),
59 ReadLong(), ReadFloat(),
60 ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(),
61 WriteFloat(), WriteDouble(), WriteString(), WriteStruct()
63 ******************************************************************************/
65 struct MinList _list;
66 struct FreeLevel * curr;
68 # define list ((struct List *)&_list)
70 NEWLIST(list);
72 if (!(curr = AllocMem (sizeof (struct FreeLevel), MEMF_ANY)) )
73 return;
75 AddTail (list, (struct Node *)curr);
77 curr->sd = sd;
78 curr->pos = 0;
79 curr->s = data;
81 # define DESC curr->sd[curr->pos]
82 # define IDESC curr->sd[curr->pos ++]
84 for (;;)
86 if (!curr->pos)
88 curr->size = IDESC;
91 if (DESC == SDT_END)
92 break;
94 switch (IDESC)
96 case SDT_UBYTE: /* Read one 8bit byte */
97 case SDT_UWORD: /* Read one 16bit word */
98 case SDT_ULONG: /* Read one 32bit long */
99 case SDT_FLOAT: /* Read one 32bit IEEE */
100 case SDT_DOUBLE: /* Read one 64bit IEEE */
101 case SDT_IGNORE: /* Ignore x bytes */
102 /* Ignore these */
103 curr->pos ++;
104 break;
106 case SDT_STRING: { /* Read a string */
107 STRPTR sptr;
109 sptr = *(STRPTR *)(curr->s + IDESC);
111 FreeVec (sptr);
113 break; }
115 case SDT_STRUCT: { /* Read a structure */
116 /* Ignore two parameters */
117 curr->pos += 2;
119 break; }
121 case SDT_PTR: { /* Follow a pointer */
122 struct FreeLevel * next;
124 IPTR * desc;
125 APTR * aptr;
127 aptr = ((APTR *)(curr->s + IDESC));
128 desc = (IPTR *)IDESC;
130 if (*aptr)
132 if (!(next = AllocMem (sizeof (struct FreeLevel), MEMF_ANY)) )
133 goto error;
135 AddTail (list, (struct Node *)next);
136 next->sd = desc;
137 next->pos = 0;
138 next->s = *aptr;
140 curr = next;
143 break; }
145 case SDT_FILL_BYTE: /* Fill x bytes */
146 case SDT_FILL_LONG: /* Fill x longs */
147 case SDT_IFILL_BYTE: /* Fill x bytes */
148 case SDT_IFILL_LONG: /* Fill x longs */
149 curr->pos += 3; /* Ignore three parameters */
150 break;
152 case SDT_SPECIAL: { /* Call user hook */
153 struct Hook * hook;
154 struct SDData data;
156 data.sdd_Dest = ((APTR)(curr->s + IDESC));
157 data.sdd_Mode = SDV_SPECIALMODE_FREE;
159 hook = (struct Hook *)IDESC;
161 CallHookA (hook, NULL, &data);
163 break; }
165 } /* switch */
167 /* End of the description list ? */
168 if (DESC == SDT_END)
170 struct FreeLevel * last;
172 /* Remove the current level */
173 last = curr;
174 Remove ((struct Node *)last);
176 /* Get the last level */
177 if ((curr = (struct FreeLevel *)GetTail (list)))
179 FreeMem (last->s, last->size);
180 FreeMem (last, sizeof (struct FreeLevel));
182 else
184 curr = last;
187 } /* while */
189 FreeMem (curr->s, curr->size);
190 FreeMem (curr, sizeof (struct FreeLevel));
192 return;
194 error:
195 while ((curr = (struct FreeLevel *)RemTail (list)))
196 FreeMem (curr, sizeof (struct FreeLevel));
197 } /* FreeStruct */