Correctly access platform data via function argument.
[AROS.git] / compiler / arossupport / freestruct.c
blob5004fcdfcd9a77945b9e76b0b1cdd3062b8a289f
1 /*
2 Copyright © 1995-2007, 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 exec.library/Open(), exec.library/Close(), ReadByte(), ReadWord(),
59 ReadLong(), ReadFloat(),
60 ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(),
61 WriteFloat(), WriteDouble(), WriteString(), WriteStruct()
63 HISTORY
64 29.11.96 ada created
66 ******************************************************************************/
68 struct MinList _list;
69 struct FreeLevel * curr;
71 # define list ((struct List *)&_list)
73 NEWLIST(list);
75 if (!(curr = AllocMem (sizeof (struct FreeLevel), MEMF_ANY)) )
76 return;
78 AddTail (list, (struct Node *)curr);
80 curr->sd = sd;
81 curr->pos = 0;
82 curr->s = data;
84 # define DESC curr->sd[curr->pos]
85 # define IDESC curr->sd[curr->pos ++]
87 for (;;)
89 if (!curr->pos)
91 curr->size = IDESC;
94 if (DESC == SDT_END)
95 break;
97 switch (IDESC)
99 case SDT_UBYTE: /* Read one 8bit byte */
100 case SDT_UWORD: /* Read one 16bit word */
101 case SDT_ULONG: /* Read one 32bit long */
102 case SDT_FLOAT: /* Read one 32bit IEEE */
103 case SDT_DOUBLE: /* Read one 64bit IEEE */
104 case SDT_IGNORE: /* Ignore x bytes */
105 /* Ignore these */
106 curr->pos ++;
107 break;
109 case SDT_STRING: { /* Read a string */
110 STRPTR sptr;
112 sptr = *(STRPTR *)(curr->s + IDESC);
114 if (sptr)
115 FreeVec (sptr);
117 break; }
119 case SDT_STRUCT: { /* Read a structure */
120 /* Ignore two parameters */
121 curr->pos += 2;
123 break; }
125 case SDT_PTR: { /* Follow a pointer */
126 struct FreeLevel * next;
128 IPTR * desc;
129 APTR * aptr;
131 aptr = ((APTR *)(curr->s + IDESC));
132 desc = (IPTR *)IDESC;
134 if (*aptr)
136 if (!(next = AllocMem (sizeof (struct FreeLevel), MEMF_ANY)) )
137 goto error;
139 AddTail (list, (struct Node *)next);
140 next->sd = desc;
141 next->pos = 0;
142 next->s = *aptr;
144 curr = next;
147 break; }
149 case SDT_FILL_BYTE: /* Fill x bytes */
150 case SDT_FILL_LONG: /* Fill x longs */
151 case SDT_IFILL_BYTE: /* Fill x bytes */
152 case SDT_IFILL_LONG: /* Fill x longs */
153 curr->pos += 3; /* Ignore three parameters */
154 break;
156 case SDT_SPECIAL: { /* Call user hook */
157 struct Hook * hook;
158 struct SDData data;
160 data.sdd_Dest = ((APTR)(curr->s + IDESC));
161 data.sdd_Mode = SDV_SPECIALMODE_FREE;
163 hook = (struct Hook *)IDESC;
165 CallHookA (hook, NULL, &data);
167 break; }
169 } /* switch */
171 /* End of the description list ? */
172 if (DESC == SDT_END)
174 struct FreeLevel * last;
176 /* Remove the current level */
177 last = curr;
178 Remove ((struct Node *)last);
180 /* Get the last level */
181 if ((curr = (struct FreeLevel *)GetTail (list)))
183 FreeMem (last->s, last->size);
184 FreeMem (last, sizeof (struct FreeLevel));
186 else
188 curr = last;
191 } /* while */
193 FreeMem (curr->s, curr->size);
194 FreeMem (curr, sizeof (struct FreeLevel));
196 return;
198 error:
199 while ((curr = (struct FreeLevel *)RemTail (list)))
200 FreeMem (curr, sizeof (struct FreeLevel));
201 } /* FreeStruct */