Fixed semaphore handling code that was mistakingly removed from port (pointed out...
[cake.git] / compiler / arossupport / writestruct.c
blobb3a0b7c857fbb4b67e4e8950f01b3909d3c5416d
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Write a big endian structure to a streamhook
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 WriteLevel
18 struct MinNode node;
19 const IPTR * sd;
20 UBYTE * s;
21 int pos;
24 /******************************************************************************
26 NAME */
27 #include <stdio.h>
28 #include <aros/bigendianio.h>
29 #include <proto/alib.h>
31 BOOL WriteStruct (
33 /* SYNOPSIS */
34 struct Hook * hook,
35 void * data,
36 void * stream,
37 const IPTR * sd)
39 /* FUNCTION
40 Writes one big endian structure to a streamhook.
42 INPUTS
43 hook - Write to this streamhook
44 data - Data to be written
45 stream - Stream passed to streamhook
46 sd - Description of the structure to be written. The first element
47 is the size of the structure.
49 RESULT
50 The function returns TRUE on success and FALSE otherwise. In error,
51 you can examine IoErr() to find out what was wrong.
53 NOTES
54 This function writes big endian values to a file even on little
55 endian machines.
57 EXAMPLE
58 See ReadStruct().
60 BUGS
62 INTERNALS
63 The function uses the Write*()-functions to write data into
64 the file.
66 Pointers are written as <valid><data structure>, where valid is
67 a byte with the values 1 (then the full data structure follows)
68 or 0 (then nothing follows and the pointer will be intialized as
69 NULL when the structure is read back).
71 SEE ALSO
72 ReadByte(), ReadWord(), ReadLong(), ReadFloat(), ReadDouble(),
73 ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(),
74 WriteFloat(), WriteDouble(), WriteString(), WriteStruct()
76 HISTORY
78 ******************************************************************************/
80 struct MinList _list;
81 struct WriteLevel * curr;
83 # define list ((struct List *)&_list)
85 NEWLIST(list);
87 if (!(curr = AllocMem (sizeof (struct WriteLevel), MEMF_ANY)) )
88 return FALSE;
90 AddTail (list, (struct Node *)curr);
92 curr->sd = sd;
93 curr->pos = 1; /* Ignore size */
94 curr->s = data;
96 # define DESC (curr->sd[curr->pos])
97 # define IDESC (curr->sd[curr->pos ++])
99 while (DESC != SDT_END)
101 switch (IDESC)
103 case SDT_UBYTE: /* Write one 8bit byte */
104 if (!WriteByte (hook, *((UBYTE *)(curr->s + IDESC)), stream))
105 goto error;
107 break;
109 case SDT_UWORD: /* Write one 16bit word */
110 if (!WriteWord (hook, *((UWORD *)(curr->s + IDESC)), stream))
111 goto error;
113 break;
115 case SDT_ULONG: /* Write one 32bit long */
116 if (!WriteLong (hook, *((ULONG *)(curr->s + IDESC)), stream))
117 goto error;
119 break;
121 case SDT_FLOAT: /* Write one 32bit IEEE */
122 if (!WriteFloat (hook, *((FLOAT *)(curr->s + IDESC)), stream))
123 goto error;
125 break;
127 case SDT_DOUBLE: /* Write one 64bit IEEE */
128 if (!WriteDouble (hook, *((DOUBLE *)(curr->s + IDESC)), stream))
129 goto error;
131 break;
133 case SDT_STRING: { /* Write a string */
134 STRPTR str;
136 str = *((STRPTR *)(curr->s + IDESC));
138 if (str)
140 if (!WriteByte (hook, 1, stream))
141 goto error;
143 if (!WriteString (hook, str, stream))
144 goto error;
146 else
148 if (!WriteByte (hook, 0, stream))
149 goto error;
151 curr->pos ++;
154 break; }
156 case SDT_STRUCT: { /* Write a structure */
157 struct WriteLevel * next;
159 IPTR * desc;
160 APTR ptr;
162 ptr = (APTR)(curr->s + IDESC);
163 desc = (IPTR *)IDESC;
165 if (!(next = AllocMem (sizeof (struct WriteLevel), MEMF_ANY)) )
166 goto error;
168 AddTail (list, (struct Node *)next);
169 next->sd = desc;
170 next->pos = 1; /* Ignore size */
171 next->s = ptr;
173 curr = next;
175 break; }
177 case SDT_PTR: { /* Follow a pointer */
178 struct WriteLevel * next;
180 IPTR * desc;
181 APTR ptr;
183 ptr = *((APTR *)(curr->s + IDESC));
184 desc = (IPTR *)IDESC;
186 if (ptr)
188 if (!WriteByte (hook, 1, stream))
189 goto error;
191 if (!(next = AllocMem (sizeof (struct WriteLevel), MEMF_ANY)) )
192 goto error;
194 AddTail (list, (struct Node *)next);
195 next->sd = desc;
196 next->pos = 1;
197 next->s = ptr;
199 curr = next;
201 else
203 if (!WriteByte (hook, 0, stream))
204 goto error;
206 curr->pos ++;
209 break; }
211 case SDT_IGNORE: { /* Ignore x bytes */
212 ULONG count;
213 struct BEIOM_Write wr = {BEIO_WRITE, 0};
215 count = IDESC;
217 while (count --)
219 if (CallHookA (hook, stream, &wr) == EOF)
220 goto error;
223 break; }
225 case SDT_FILL_BYTE: /* Fill x bytes */
226 case SDT_FILL_LONG: /* Fill x longs */
227 /* ignore */
228 break;
230 case SDT_IFILL_BYTE: { /* Fill x bytes */
231 IPTR offset;
232 UBYTE value;
233 IPTR count;
235 struct BEIOM_Write wr = {BEIO_WRITE, 0};
237 offset = IDESC;
238 value = IDESC;
239 count = IDESC;
241 while (count --)
243 if (CallHookA (hook, stream, &wr) == EOF)
244 goto error;
247 break; }
249 case SDT_IFILL_LONG: { /* Fill x longs */
250 IPTR offset;
251 UBYTE value;
252 IPTR count;
253 struct BEIOM_Write wr = {BEIO_WRITE, 0};
255 offset = IDESC;
256 value = IDESC;
257 count = IDESC;
259 count <<= 2;
261 while (count --)
263 if (CallHookA (hook, stream, &wr) == EOF)
264 goto error;
267 break; }
269 case SDT_SPECIAL: { /* Call user hook */
270 struct Hook * uhook;
271 struct SDData data;
273 data.sdd_Dest = ((APTR)(curr->s + IDESC));
274 data.sdd_Mode = SDV_SPECIALMODE_WRITE;
275 data.sdd_Stream = stream;
277 uhook = (struct Hook *)IDESC;
279 CallHookA (uhook, hook, &data);
281 break; }
283 default:
284 goto error;
286 } /* switch */
288 /* End of the description list ? */
289 if (DESC == SDT_END)
291 struct WriteLevel * last;
293 /* Remove the current level */
294 last = curr;
295 Remove ((struct Node *)last);
297 /* Get the last level */
298 if ((curr = (struct WriteLevel *)GetTail (list)))
300 FreeMem (last, sizeof (struct WriteLevel));
302 else
304 curr = last;
307 } /* while */
309 FreeMem (curr, sizeof (struct WriteLevel));
311 return TRUE;
313 error:
315 while ((curr = (struct WriteLevel *)RemTail (list)))
316 FreeMem (curr, sizeof (struct WriteLevel));
318 return FALSE;
319 } /* WriteStruct */