2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Read a big endian structure from a streamhook
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>
24 /******************************************************************************
28 #include <aros/bigendianio.h>
29 #include <proto/alib.h>
40 Reads one big endian structure from a 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.
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.
55 This function reads big endian values from a streamhook even on
56 little endian machines.
64 ReadByte(), ReadWord(), ReadLong(), ReadFloat(), ReadDouble(),
65 ReadString(), ReadStruct(), WriteByte(), WriteWord(), WriteLong(),
66 WriteFloat(), WriteDouble(), WriteString(), WriteStruct()
70 ******************************************************************************/
74 struct ReadLevel
* curr
;
76 # define list ((struct List *)&_list)
80 if (!(curr
= AllocMem (sizeof (struct ReadLevel
), MEMF_ANY
)) )
83 AddTail (list
, (struct Node
*)curr
);
89 # define DESC curr->sd[curr->pos]
90 # define IDESC curr->sd[curr->pos ++]
96 if (!(curr
->s
= AllocMem (IDESC
, MEMF_CLEAR
)) )
105 case SDT_UBYTE
: /* Read one 8bit byte */
106 if (!ReadByte (hook
, (UBYTE
*)(curr
->s
+ IDESC
), stream
))
111 case SDT_UWORD
: /* Read one 16bit word */
112 if (!ReadWord (hook
, (UWORD
*)(curr
->s
+ IDESC
), stream
))
117 case SDT_ULONG
: /* Read one 32bit long */
118 if (!ReadLong (hook
, (ULONG
*)(curr
->s
+ IDESC
), stream
))
123 case SDT_FLOAT
: /* Read one 32bit IEEE */
124 if (!ReadFloat (hook
, (FLOAT
*)(curr
->s
+ IDESC
), stream
))
129 case SDT_DOUBLE
: /* Read one 64bit IEEE */
130 if (!ReadDouble (hook
, (DOUBLE
*)(curr
->s
+ IDESC
), stream
))
135 case SDT_STRING
: { /* Read a string */
139 sptr
= (STRPTR
*)(curr
->s
+ IDESC
);
141 if (!ReadByte (hook
, &valid_ptr
, stream
))
146 if (!ReadString (hook
, sptr
, stream
))
156 case SDT_STRUCT
: { /* Read a structure */
157 struct ReadLevel
* next
;
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
)) )
169 AddTail (list
, (struct Node
*)next
);
178 case SDT_PTR
: { /* Follow a pointer */
179 struct ReadLevel
* next
;
185 aptr
= ((APTR
*)(curr
->s
+ IDESC
));
186 desc
= (IPTR
*)IDESC
;
188 if (!ReadByte (hook
, &valid_ptr
, stream
))
195 if (!(next
= AllocMem (sizeof (struct ReadLevel
), MEMF_ANY
)) )
198 AddTail (list
, (struct Node
*)next
);
211 case SDT_IGNORE
: /* Ignore x bytes */
212 if (CallHook (hook
, stream
, BEIO_IGNORE
, IDESC
) == EOF
)
217 case SDT_FILL_BYTE
: { /* Fill x bytes */
226 memset (curr
->s
+ offset
, value
, count
);
230 case SDT_FILL_LONG
: { /* Fill x longs */
235 ulptr
= (ULONG
*)(curr
->s
+ IDESC
);
244 case SDT_IFILL_BYTE
: { /* Fill x bytes */
253 if (CallHook (hook
, stream
, BEIO_IGNORE
, count
) == EOF
)
256 memset (curr
->s
+ offset
, value
, count
);
260 case SDT_IFILL_LONG
: { /* Fill x longs */
265 ulptr
= (ULONG
*)(curr
->s
+ IDESC
);
269 if (CallHook (hook
, stream
, BEIO_IGNORE
, count
<<2) == EOF
)
277 case SDT_SPECIAL
: { /* Call user hook */
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
))
297 /* End of the description list ? */
300 struct ReadLevel
* last
;
302 /* Remove the current level */
304 Remove ((struct Node
*)last
);
306 /* Get the last level */
307 if ((curr
= (struct ReadLevel
*)GetTail (list
)))
312 curr
->pos
+= 2; /* Skip 2 parameters */
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.
331 FreeMem (last
, sizeof (struct ReadLevel
));
342 FreeMem (curr
, sizeof (struct ReadLevel
));
347 curr
= (struct ReadLevel
*)GetHead (list
);
350 FreeStruct (curr
->s
, curr
->sd
);
352 while ((curr
= (struct ReadLevel
*)RemTail (list
)))
353 FreeMem (curr
, sizeof (struct ReadLevel
));
361 #include <aros/structdesc.h>
362 #include <proto/alib.h>
381 struct Level1 ml_Level1
;
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)
402 sizeof (struct Level1
),
403 SDM_UBYTE(O(l1_Byte
)),
404 SDM_ULONG(O(l1_Long
)),
409 #define O(x) offsetof(struct MainLevel,x)
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
),
435 LONG
dosstreamhook (struct Hook
* hook
, BPTR fh
, ULONG
* msg
);
439 { NULL
, NULL
}, HookEntry
, (void *)dosstreamhook
, NULL
442 LONG
dosstreamhook (struct Hook
* hook
, BPTR fh
, ULONG
* msg
)
453 rc
= FPutC (fh
, ((struct BEIOM_Write
*)msg
)->Data
);
459 rc
= Seek (fh
, ((struct BEIOM_Ignore
*)msg
)->Count
, OFFSET_CURRENT
);
465 } /* dosstreamhook */
467 int main (int argc
, char ** argv
)
469 struct MainLevel demo
=
472 (WORD
)0x8844, 0xFF77,
473 (LONG
)0x88442211, 0xFF773311,
476 { (BYTE
)0x88, (LONG
)0x88442211 },
480 WORD w
= (WORD
)0x8844;
481 LONG l
= (LONG
)0x88442211;
487 (BYTE
)0x88, (LONG
)0x88442211
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
);
504 PrintFault (IoErr(), "Can't open file\n");
509 This writes the following data stream:
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");
538 PrintFault (IoErr(), "Failed to close file\n");
541 /* Read the structure back */
542 fh
= Open ("writestruct.dat", MODE_OLDFILE
);
546 PrintFault (IoErr(), "Can't open file for reading\n");
550 if (!ReadStruct (&dsh
, (APTR
*)&readback
, fh
, MainDesc
))
552 PrintFault (IoErr(), "Failed to read from file\n");
559 ptr
= (UBYTE
*)readback
;
562 kprintf ("readback = %p\n", readback
);
564 kprintf ("%02X (88) %02X (FF)\n"
565 , (UBYTE
)readback
->ml_Byte
568 kprintf ("%04X (8844) %04X (FF77)\n"
569 , (UWORD
)readback
->ml_Word
572 kprintf ("%08lX (88442211) %08lX (FF773311)\n"
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
);
615 PrintFault (IoErr(), "Failed to close file after reading\n");