Indentation fix, cleanup.
[AROS.git] / compiler / arossupport / writestruct.c
blob48c5765ef190098ffc99f487718559be1bf17935
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 count;
233 struct BEIOM_Write wr = {BEIO_WRITE, 0};
235 count = IDESC;
237 while (count --)
239 if (CallHookA (hook, stream, &wr) == EOF)
240 goto error;
243 break; }
245 case SDT_IFILL_LONG: { /* Fill x longs */
246 IPTR count;
247 struct BEIOM_Write wr = {BEIO_WRITE, 0};
249 count = IDESC;
251 count <<= 2;
253 while (count --)
255 if (CallHookA (hook, stream, &wr) == EOF)
256 goto error;
259 break; }
261 case SDT_SPECIAL: { /* Call user hook */
262 struct Hook * uhook;
263 struct SDData data;
265 data.sdd_Dest = ((APTR)(curr->s + IDESC));
266 data.sdd_Mode = SDV_SPECIALMODE_WRITE;
267 data.sdd_Stream = stream;
269 uhook = (struct Hook *)IDESC;
271 if (!CallHookA (uhook, hook, &data))
272 goto error;
274 break; }
276 default:
277 goto error;
279 } /* switch */
281 /* End of the description list ? */
282 if (DESC == SDT_END)
284 struct WriteLevel * last;
286 /* Remove the current level */
287 last = curr;
288 Remove ((struct Node *)last);
290 /* Get the last level */
291 if ((curr = (struct WriteLevel *)GetTail (list)))
293 FreeMem (last, sizeof (struct WriteLevel));
295 else
297 curr = last;
300 } /* while */
302 FreeMem (curr, sizeof (struct WriteLevel));
304 return TRUE;
306 error:
308 while ((curr = (struct WriteLevel *)RemTail (list)))
309 FreeMem (curr, sizeof (struct WriteLevel));
311 return FALSE;
312 } /* WriteStruct */