tabs->spaces
[AROS.git] / compiler / arossupport / writestruct.c
blobe8ce3956183acb119a64896b9e65c23472a3b6f8
1 /*
2 Copyright © 1995-2018, 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
61 SDT_SPECIAL not implemented.
63 INTERNALS
64 The function uses the Write*()-functions to write data into
65 the file.
67 Pointers are written as <valid><data structure>, where valid is
68 a byte with the values 1 (then the full data structure follows)
69 or 0 (then nothing follows and the pointer will be intialized as
70 NULL when the structure is read back).
72 SEE ALSO
73 ReadByte(), ReadWord(), ReadLong(), ReadFloat(), ReadDouble(),
74 ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(),
75 WriteFloat(), WriteDouble(), WriteString(), WriteStruct()
77 HISTORY
79 ******************************************************************************/
81 struct MinList _list;
82 struct WriteLevel * curr;
84 # define list ((struct List *)&_list)
86 NEWLIST(list);
88 if (!(curr = AllocMem (sizeof (struct WriteLevel), MEMF_ANY)) )
89 return FALSE;
91 AddTail (list, (struct Node *)curr);
93 curr->sd = sd;
94 curr->pos = 1; /* Ignore size */
95 curr->s = data;
97 # define DESC (curr->sd[curr->pos])
98 # define IDESC (curr->sd[curr->pos ++])
100 while (DESC != SDT_END)
102 switch (IDESC)
104 case SDT_UBYTE: /* Write one 8bit byte */
105 if (!WriteByte (hook, *((UBYTE *)(curr->s + IDESC)), stream))
106 goto error;
108 break;
110 case SDT_UWORD: /* Write one 16bit word */
111 if (!WriteWord (hook, *((UWORD *)(curr->s + IDESC)), stream))
112 goto error;
114 break;
116 case SDT_ULONG: /* Write one 32bit long */
117 if (!WriteLong (hook, *((ULONG *)(curr->s + IDESC)), stream))
118 goto error;
120 break;
122 case SDT_FLOAT: /* Write one 32bit IEEE */
123 if (!WriteFloat (hook, *((FLOAT *)(curr->s + IDESC)), stream))
124 goto error;
126 break;
128 case SDT_DOUBLE: /* Write one 64bit IEEE */
129 if (!WriteDouble (hook, *((DOUBLE *)(curr->s + IDESC)), stream))
130 goto error;
132 break;
134 case SDT_COPY: { /* Copy 'n' bytes */
135 int i, count, offset ;
137 offset = IDESC;
138 count = IDESC;
140 for (i=0; i<count; i++)
142 if (!WriteByte (hook, *((UBYTE *)(curr->s + offset + i)), stream))
143 goto error;
146 break; }
148 case SDT_STRING: { /* Write a string */
149 STRPTR str;
151 str = *((STRPTR *)(curr->s + IDESC));
153 if (str)
155 if (!WriteByte (hook, 1, stream))
156 goto error;
158 if (!WriteString (hook, str, stream))
159 goto error;
161 else
163 if (!WriteByte (hook, 0, stream))
164 goto error;
166 curr->pos ++;
169 break; }
171 case SDT_STRUCT: { /* Write a structure */
172 struct WriteLevel * next;
174 IPTR * desc;
175 APTR ptr;
177 ptr = (APTR)(curr->s + IDESC);
178 desc = (IPTR *)IDESC;
180 if (!(next = AllocMem (sizeof (struct WriteLevel), MEMF_ANY)) )
181 goto error;
183 AddTail (list, (struct Node *)next);
184 next->sd = desc;
185 next->pos = 1; /* Ignore size */
186 next->s = ptr;
188 curr = next;
190 break; }
192 case SDT_PTR: { /* Follow a pointer */
193 struct WriteLevel * next;
195 IPTR * desc;
196 APTR ptr;
198 ptr = *((APTR *)(curr->s + IDESC));
199 desc = (IPTR *)IDESC;
201 if (ptr)
203 if (!WriteByte (hook, 1, stream))
204 goto error;
206 if (!(next = AllocMem (sizeof (struct WriteLevel), MEMF_ANY)) )
207 goto error;
209 AddTail (list, (struct Node *)next);
210 next->sd = desc;
211 next->pos = 1;
212 next->s = ptr;
214 curr = next;
216 else
218 if (!WriteByte (hook, 0, stream))
219 goto error;
221 curr->pos ++;
224 break; }
226 case SDT_IGNORE: { /* Ignore x bytes */
227 ULONG count;
228 struct BEIOM_Write wr = {BEIO_WRITE, 0};
230 count = IDESC;
232 while (count --)
234 if (CallHookA (hook, stream, &wr) == EOF)
235 goto error;
238 break; }
240 case SDT_FILL_BYTE: /* Fill x bytes */
241 case SDT_FILL_LONG: /* Fill x longs */
242 /* ignore */
243 break;
245 case SDT_IFILL_BYTE: { /* Fill x bytes */
246 IPTR count;
248 struct BEIOM_Write wr = {BEIO_WRITE, 0};
250 count = IDESC;
252 while (count --)
254 if (CallHookA (hook, stream, &wr) == EOF)
255 goto error;
258 break; }
260 case SDT_IFILL_LONG: { /* Fill x longs */
261 IPTR count;
262 struct BEIOM_Write wr = {BEIO_WRITE, 0};
264 count = IDESC;
266 count <<= 2;
268 while (count --)
270 if (CallHookA (hook, stream, &wr) == EOF)
271 goto error;
274 break; }
276 case SDT_SPECIAL: { /* Call user hook */
277 struct Hook * uhook;
278 struct SDData data;
280 data.sdd_Dest = ((APTR)(curr->s + IDESC));
281 data.sdd_Mode = SDV_SPECIALMODE_WRITE;
282 data.sdd_Stream = stream;
284 uhook = (struct Hook *)IDESC;
286 if (!CallHookA (uhook, hook, &data))
287 goto error;
289 break; }
291 default:
292 goto error;
294 } /* switch */
296 /* End of the description list ? */
297 if (DESC == SDT_END)
299 struct WriteLevel * last;
301 /* Remove the current level */
302 last = curr;
303 Remove ((struct Node *)last);
305 /* Get the last level */
306 if ((curr = (struct WriteLevel *)GetTail (list)))
308 FreeMem (last, sizeof (struct WriteLevel));
310 else
312 curr = last;
315 } /* while */
317 FreeMem (curr, sizeof (struct WriteLevel));
319 return TRUE;
321 error:
323 while ((curr = (struct WriteLevel *)RemTail (list)))
324 FreeMem (curr, sizeof (struct WriteLevel));
326 return FALSE;
327 } /* WriteStruct */