Added DefaultWindowShapeFunc. Calls WDM_WINDOWSHAPE.
[tangerine.git] / compiler / arossupport / readstruct.c
blob781eca6c8d4aaf40021ef6c86d24a1d9ba37a08c
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Read a big endian structure from 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 ReadLevel
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 ReadStruct (
33 /* SYNOPSIS */
34 struct Hook * hook,
35 APTR * dataptr,
36 void * stream,
37 const IPTR * sd)
39 /* FUNCTION
40 Reads one big endian structure from a streamhook.
42 INPUTS
43 hook - Streamhook
44 dataptr - Put the data here
45 stream - Read from this stream
46 sd - Description of the structure to be read. The first element
47 is the size of the structure.
49 RESULT
50 The function returns TRUE on success. On success, the value
51 read is written into dataptr. On failure, FALSE is returned and the
52 contents of dataptr are not changed.
54 NOTES
55 This function reads big endian values from a streamhook even on
56 little endian machines.
58 EXAMPLE
59 See below.
61 BUGS
63 SEE ALSO
64 ReadByte(), ReadWord(), ReadLong(), ReadFloat(), ReadDouble(),
65 ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(),
66 WriteFloat(), WriteDouble(), WriteString(), WriteStruct()
68 HISTORY
70 ******************************************************************************/
72 AROS_GET_SYSBASE_OK
73 struct MinList _list;
74 struct ReadLevel * curr;
76 # define list ((struct List *)&_list)
78 NEWLIST(list);
80 if (!(curr = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) )
81 return FALSE;
83 AddTail (list, (struct Node *)curr);
85 curr->sd = sd;
86 curr->pos = 0;
87 curr->s = NULL;
89 # define DESC curr->sd[curr->pos]
90 # define IDESC curr->sd[curr->pos ++]
92 for (;;)
94 if (!curr->pos)
96 if (!(curr->s = AllocMem (IDESC, MEMF_CLEAR)) )
97 goto error;
100 if (DESC == SDT_END)
101 break;
103 switch (IDESC)
105 case SDT_UBYTE: /* Read one 8bit byte */
106 if (!ReadByte (hook, (UBYTE *)(curr->s + IDESC), stream))
107 goto error;
109 break;
111 case SDT_UWORD: /* Read one 16bit word */
112 if (!ReadWord (hook, (UWORD *)(curr->s + IDESC), stream))
113 goto error;
115 break;
117 case SDT_ULONG: /* Read one 32bit long */
118 if (!ReadLong (hook, (ULONG *)(curr->s + IDESC), stream))
119 goto error;
121 break;
123 case SDT_FLOAT: /* Read one 32bit IEEE */
124 if (!ReadFloat (hook, (FLOAT *)(curr->s + IDESC), stream))
125 goto error;
127 break;
129 case SDT_DOUBLE: /* Read one 64bit IEEE */
130 if (!ReadDouble (hook, (DOUBLE *)(curr->s + IDESC), stream))
131 goto error;
133 break;
135 case SDT_STRING: { /* Read a string */
136 UBYTE valid_ptr;
137 STRPTR * sptr;
139 sptr = (STRPTR *)(curr->s + IDESC);
141 if (!ReadByte (hook, &valid_ptr, stream))
142 goto error;
144 if (valid_ptr)
146 if (!ReadString (hook, sptr, stream))
147 goto error;
149 else
151 *sptr = NULL;
154 break; }
156 case SDT_STRUCT: { /* Read a structure */
157 struct ReadLevel * next;
158 IPTR * desc;
159 APTR aptr;
161 aptr = (APTR)(curr->s + IDESC);
162 desc = (IPTR *)IDESC;
164 curr->pos -= 3; /* Go back to type */
166 if (!(next = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) )
167 goto error;
169 AddTail (list, (struct Node *)next);
170 next->sd = desc;
171 next->pos = 1;
172 next->s = aptr;
174 curr = next;
176 break; }
178 case SDT_PTR: { /* Follow a pointer */
179 struct ReadLevel * next;
181 UBYTE valid_ptr;
182 IPTR * desc;
183 APTR * aptr;
185 aptr = ((APTR *)(curr->s + IDESC));
186 desc = (IPTR *)IDESC;
188 if (!ReadByte (hook, &valid_ptr, stream))
189 goto error;
191 if (valid_ptr)
193 curr->pos -= 3;
195 if (!(next = AllocMem (sizeof (struct ReadLevel), MEMF_ANY)) )
196 goto error;
198 AddTail (list, (struct Node *)next);
199 next->sd = desc;
200 next->pos = 0;
202 curr = next;
204 else
206 *aptr = NULL;
209 break; }
211 case SDT_IGNORE: /* Ignore x bytes */
212 if (CallHook (hook, stream, BEIO_IGNORE, IDESC) == EOF)
213 goto error;
215 break;
217 case SDT_FILL_BYTE: { /* Fill x bytes */
218 IPTR offset;
219 UBYTE value;
220 IPTR count;
222 offset = IDESC;
223 value = IDESC;
224 count = IDESC;
226 memset (curr->s + offset, value, count);
228 break; }
230 case SDT_FILL_LONG: { /* Fill x longs */
231 ULONG * ulptr;
232 ULONG value;
233 IPTR count;
235 ulptr = (ULONG *)(curr->s + IDESC);
236 value = IDESC;
237 count = IDESC;
239 while (count --)
240 *ulptr ++ = value;
242 break; }
244 case SDT_IFILL_BYTE: { /* Fill x bytes */
245 IPTR offset;
246 UBYTE value;
247 IPTR count;
249 offset = IDESC;
250 value = IDESC;
251 count = IDESC;
253 if (CallHook (hook, stream, BEIO_IGNORE, count) == EOF)
254 goto error;
256 memset (curr->s + offset, value, count);
258 break; }
260 case SDT_IFILL_LONG: { /* Fill x longs */
261 ULONG * ulptr;
262 ULONG value;
263 IPTR count;
265 ulptr = (ULONG *)(curr->s + IDESC);
266 value = IDESC;
267 count = IDESC;
269 if (CallHook (hook, stream, BEIO_IGNORE, count<<2) == EOF)
270 goto error;
272 while (count --)
273 *ulptr ++ = value;
275 break; }
277 case SDT_SPECIAL: { /* Call user hook */
278 struct Hook * uhook;
279 struct SDData data;
281 data.sdd_Dest = ((APTR)(curr->s + IDESC));
282 data.sdd_Mode = SDV_SPECIALMODE_READ;
283 data.sdd_Stream = stream;
285 uhook = (struct Hook *)IDESC;
287 if (!CallHookA (uhook, hook, &data))
288 goto error;
290 break; }
292 default:
293 goto error;
295 } /* switch */
297 /* End of the description list ? */
298 if (DESC == SDT_END)
300 struct ReadLevel * last;
302 /* Remove the current level */
303 last = curr;
304 Remove ((struct Node *)last);
306 /* Get the last level */
307 if ((curr = (struct ReadLevel *)GetTail (list)))
309 switch (IDESC)
311 case SDT_STRUCT:
312 curr->pos += 2; /* Skip 2 parameters */
313 break;
315 case SDT_PTR: {
316 APTR * aptr;
318 aptr = ((APTR *)(curr->s + IDESC));
319 curr->pos ++; /* Skip description parameter */
322 Now put the result of the current level in the
323 struct of the previous level.
325 *aptr = last->s;
327 break; }
331 FreeMem (last, sizeof (struct ReadLevel));
333 else
335 curr = last;
338 } /* while */
340 *dataptr = curr->s;
342 FreeMem (curr, sizeof (struct ReadLevel));
344 return TRUE;
346 error:
347 curr = (struct ReadLevel *)GetHead (list);
349 if (curr && curr->s)
350 FreeStruct (curr->s, curr->sd);
352 while ((curr = (struct ReadLevel *)RemTail (list)))
353 FreeMem (curr, sizeof (struct ReadLevel));
355 return FALSE;
356 } /* ReadStruct */
358 #ifdef TEST
359 #include <stdio.h>
360 #include <dos/dos.h>
361 #include <aros/structdesc.h>
362 #include <proto/alib.h>
364 struct Level1
366 BYTE l1_Byte;
367 LONG l1_Long;
370 struct MainLevel
372 BYTE ml_Byte;
373 UBYTE ml_UByte;
374 WORD ml_Word;
375 UWORD ml_UWord;
376 LONG ml_Long;
377 ULONG ml_ULong;
378 FLOAT ml_Float;
379 DOUBLE ml_Double;
380 STRPTR ml_String;
381 struct Level1 ml_Level1;
383 BYTE * ml_BytePtr;
384 WORD * ml_WordPtr;
385 LONG * ml_LongPtr;
386 FLOAT * ml_FloatPtr;
387 DOUBLE * ml_DoublePtr;
388 STRPTR * ml_StringPtr;
389 struct Level1 * ml_Level1Ptr;
392 IPTR ByteDesc[] = { sizeof(UBYTE), SDM_UBYTE(0), SDM_END };
393 IPTR WordDesc[] = { sizeof(UWORD), SDM_UWORD(0), SDM_END };
394 IPTR LongDesc[] = { sizeof(ULONG), SDM_ULONG(0), SDM_END };
395 IPTR FloatDesc[] = { sizeof(FLOAT), SDM_FLOAT(0), SDM_END };
396 IPTR DoubleDesc[] = { sizeof(DOUBLE), SDM_DOUBLE(0), SDM_END };
397 IPTR StringDesc[] = { sizeof(STRPTR), SDM_STRING(0), SDM_END };
399 #define O(x) offsetof(struct Level1,x)
400 IPTR Level1Desc[] =
402 sizeof (struct Level1),
403 SDM_UBYTE(O(l1_Byte)),
404 SDM_ULONG(O(l1_Long)),
405 SDM_END
408 #undef O
409 #define O(x) offsetof(struct MainLevel,x)
410 IPTR MainDesc[] =
412 sizeof (struct MainLevel),
413 SDM_UBYTE(O(ml_Byte)),
414 SDM_UBYTE(O(ml_UByte)),
415 SDM_UWORD(O(ml_Word)),
416 SDM_UWORD(O(ml_UWord)),
417 SDM_ULONG(O(ml_Long)),
418 SDM_ULONG(O(ml_ULong)),
419 SDM_FLOAT(O(ml_Float)),
420 SDM_DOUBLE(O(ml_Double)),
421 SDM_STRING(O(ml_String)),
422 SDM_STRUCT(O(ml_Level1),Level1Desc),
424 SDM_PTR(O(ml_BytePtr),ByteDesc),
425 SDM_PTR(O(ml_WordPtr),WordDesc),
426 SDM_PTR(O(ml_LongPtr),LongDesc),
427 SDM_PTR(O(ml_FloatPtr),FloatDesc),
428 SDM_PTR(O(ml_DoublePtr),DoubleDesc),
429 SDM_PTR(O(ml_StringPtr),StringDesc),
430 SDM_PTR(O(ml_Level1Ptr),Level1Desc),
432 SDM_END
435 LONG dosstreamhook (struct Hook * hook, BPTR fh, ULONG * msg);
437 struct Hook dsh =
439 { NULL, NULL }, HookEntry, (void *)dosstreamhook, NULL
442 LONG dosstreamhook (struct Hook * hook, BPTR fh, ULONG * msg)
444 LONG rc;
446 switch (*msg)
448 case BEIO_READ:
449 rc = FGetC (fh);
450 break;
452 case BEIO_WRITE:
453 rc = FPutC (fh, ((struct BEIOM_Write *)msg)->Data);
454 break;
456 case BEIO_IGNORE:
457 Flush (fh);
459 rc = Seek (fh, ((struct BEIOM_Ignore *)msg)->Count, OFFSET_CURRENT);
460 break;
464 return rc;
465 } /* dosstreamhook */
467 int main (int argc, char ** argv)
469 struct MainLevel demo =
471 (BYTE)0x88, 0xFF,
472 (WORD)0x8844, 0xFF77,
473 (LONG)0x88442211, 0xFF773311,
474 1.5, 1.75,
475 "Hallo",
476 { (BYTE)0x88, (LONG)0x88442211 },
477 /* ... */
479 BYTE b = (BYTE)0x88;
480 WORD w = (WORD)0x8844;
481 LONG l = (LONG)0x88442211;
482 FLOAT f = 1.5;
483 DOUBLE d = 1.75;
484 STRPTR s = "Hallo";
485 struct Level1 l1 =
487 (BYTE)0x88, (LONG)0x88442211
489 BPTR fh;
490 struct MainLevel * readback;
492 demo.ml_BytePtr = &b;
493 demo.ml_WordPtr = &w;
494 demo.ml_LongPtr = &l;
495 demo.ml_FloatPtr = &f;
496 demo.ml_DoublePtr = &d;
497 demo.ml_StringPtr = &s;
498 demo.ml_Level1Ptr = &l1;
500 fh = Open ("writestruct.dat", MODE_NEWFILE);
502 if (!fh)
504 PrintFault (IoErr(), "Can't open file\n");
505 return 10;
509 This writes the following data stream:
511 0000 88 ml_Byte
512 0001 ff ml_Ubyte
513 0002 88 44 ml_Word
514 0004 ff 77 ml_UWord
515 0006 88 44 22 11 ml_Long
516 000a ff 77 33 11 ml_ULong
517 000e 3f c0 00 00 ml_Float
518 0012 3f fc 00 00 00 00 00 00 ml_Double
519 001a 01:48 61 6c 6c 6f 00 ml_String
520 0021 88 ml_Level1.l1_Byte
521 0022 88 44 22 11 ml_Level1.l1_Long
522 0026 01:88 ml_BytePtr
523 0028 01:88 44 ml_WordPtr
524 002b 01:88 44 22 11 ml_LongPtr
525 0030 01:3f c0 00 00 ml_FloatPtr
526 0035 01:3f fc 00 00 00 00 00 00 ml_DoublePtr
527 003e 01:01:48 61 6c 6c 6f 00 ml_StringPtr - Note two 01 !
528 0046 01:88 88 44 22 11 ml_Level1Ptr
531 if (!WriteStruct (&dsh, &demo, fh, MainDesc))
533 PrintFault (IoErr(), "Failed to write to file\n");
536 if (!Close (fh))
538 PrintFault (IoErr(), "Failed to close file\n");
541 /* Read the structure back */
542 fh = Open ("writestruct.dat", MODE_OLDFILE);
544 if (!fh)
546 PrintFault (IoErr(), "Can't open file for reading\n");
547 return 10;
550 if (!ReadStruct (&dsh, (APTR *)&readback, fh, MainDesc))
552 PrintFault (IoErr(), "Failed to read from file\n");
554 else
556 UBYTE * ptr;
557 int t;
559 ptr = (UBYTE *)readback;
560 t = 0;
562 kprintf ("readback = %p\n", readback);
564 kprintf ("%02X (88) %02X (FF)\n"
565 , (UBYTE)readback->ml_Byte
566 , readback->ml_UByte
568 kprintf ("%04X (8844) %04X (FF77)\n"
569 , (UWORD)readback->ml_Word
570 , readback->ml_UWord
572 kprintf ("%08lX (88442211) %08lX (FF773311)\n"
573 , readback->ml_Long
574 , readback->ml_ULong
576 kprintf ("%08lX (3FC00000) %08lX:%08lX (3FFC0000:00000000)\n"
577 , *(ULONG *)&readback->ml_Float
578 , ((ULONG *)&readback->ml_Double)[1]
579 , ((ULONG *)&readback->ml_Double)[0]
581 kprintf ("%s (Hallo)\n"
582 , readback->ml_String
584 kprintf ("{ %02X %08X } ({ 88 88442211 })\n"
585 , (UBYTE)readback->ml_Level1.l1_Byte
586 , readback->ml_Level1.l1_Long
588 kprintf ("%02X (88)\n"
589 , (UBYTE)*readback->ml_BytePtr
591 kprintf ("%04X (8844)\n"
592 , (UWORD)*readback->ml_WordPtr
594 kprintf ("%08lX (88442211)\n"
595 , *readback->ml_LongPtr
597 kprintf ("%08lX (3FC00000) %08lX:%08lX (3FFC0000:00000000)\n"
598 , *(ULONG *)readback->ml_FloatPtr
599 , ((ULONG *)readback->ml_DoublePtr)[1]
600 , ((ULONG *)readback->ml_DoublePtr)[0]
602 kprintf ("%s (Hallo)\n"
603 , *readback->ml_StringPtr
605 kprintf ("{ %02X %08X } ({ 88 88442211 })\n"
606 , (UBYTE)readback->ml_Level1Ptr->l1_Byte
607 , readback->ml_Level1Ptr->l1_Long
610 FreeStruct (readback, MainDesc);
613 if (!Close (fh))
615 PrintFault (IoErr(), "Failed to close file after reading\n");
618 return 0;
619 } /* main */
621 #endif /* TEST */