2 Copyright © 1995-2007, 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 ******************************************************************************/
73 struct ReadLevel
* curr
;
75 # define list ((struct List *)&_list)
79 if (!(curr
= AllocMem (sizeof (struct ReadLevel
), MEMF_ANY
)) )
82 AddTail (list
, (struct Node
*)curr
);
88 # define DESC curr->sd[curr->pos]
89 # define IDESC curr->sd[curr->pos ++]
95 if (!(curr
->s
= AllocMem (IDESC
, MEMF_CLEAR
)) )
104 case SDT_UBYTE
: /* Read one 8bit byte */
105 if (!ReadByte (hook
, (UBYTE
*)(curr
->s
+ IDESC
), stream
))
110 case SDT_UWORD
: /* Read one 16bit word */
111 if (!ReadWord (hook
, (UWORD
*)(curr
->s
+ IDESC
), stream
))
116 case SDT_ULONG
: /* Read one 32bit long */
117 if (!ReadLong (hook
, (ULONG
*)(curr
->s
+ IDESC
), stream
))
122 case SDT_FLOAT
: /* Read one 32bit IEEE */
123 if (!ReadFloat (hook
, (FLOAT
*)(curr
->s
+ IDESC
), stream
))
128 case SDT_DOUBLE
: /* Read one 64bit IEEE */
129 if (!ReadDouble (hook
, (DOUBLE
*)(curr
->s
+ IDESC
), stream
))
134 case SDT_STRING
: { /* Read a string */
138 sptr
= (STRPTR
*)(curr
->s
+ IDESC
);
140 if (!ReadByte (hook
, &valid_ptr
, stream
))
145 if (!ReadString (hook
, sptr
, stream
))
155 case SDT_STRUCT
: { /* Read a structure */
156 struct ReadLevel
* next
;
160 aptr
= (APTR
)(curr
->s
+ IDESC
);
161 desc
= (IPTR
*)IDESC
;
163 curr
->pos
-= 3; /* Go back to type */
165 if (!(next
= AllocMem (sizeof (struct ReadLevel
), MEMF_ANY
)) )
168 AddTail (list
, (struct Node
*)next
);
177 case SDT_PTR
: { /* Follow a pointer */
178 struct ReadLevel
* next
;
184 aptr
= ((APTR
*)(curr
->s
+ IDESC
));
185 desc
= (IPTR
*)IDESC
;
187 if (!ReadByte (hook
, &valid_ptr
, stream
))
194 if (!(next
= AllocMem (sizeof (struct ReadLevel
), MEMF_ANY
)) )
197 AddTail (list
, (struct Node
*)next
);
210 case SDT_IGNORE
: { /* Ignore x bytes */
211 struct BEIOM_Ignore ig
= {BEIO_IGNORE
, IDESC
};
212 if (CallHookA (hook
, stream
, &ig
) == 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 struct BEIOM_Ignore ig
= {BEIO_IGNORE
, count
};
255 if (CallHookA (hook
, stream
, &ig
) == EOF
)
258 memset (curr
->s
+ offset
, value
, count
);
262 case SDT_IFILL_LONG
: { /* Fill x longs */
267 ulptr
= (ULONG
*)(curr
->s
+ IDESC
);
271 struct BEIOM_Ignore ig
= {BEIO_IGNORE
, count
<< 2};
273 if (CallHookA (hook
, stream
, &ig
) == EOF
)
281 case SDT_SPECIAL
: { /* Call user hook */
285 data
.sdd_Dest
= ((APTR
)(curr
->s
+ IDESC
));
286 data
.sdd_Mode
= SDV_SPECIALMODE_READ
;
287 data
.sdd_Stream
= stream
;
289 uhook
= (struct Hook
*)IDESC
;
291 if (!CallHookA (uhook
, hook
, &data
))
301 /* End of the description list ? */
304 struct ReadLevel
* last
;
306 /* Remove the current level */
308 Remove ((struct Node
*)last
);
310 /* Get the last level */
311 if ((curr
= (struct ReadLevel
*)GetTail (list
)))
316 curr
->pos
+= 2; /* Skip 2 parameters */
322 aptr
= ((APTR
*)(curr
->s
+ IDESC
));
323 curr
->pos
++; /* Skip description parameter */
326 Now put the result of the current level in the
327 struct of the previous level.
335 FreeMem (last
, sizeof (struct ReadLevel
));
346 FreeMem (curr
, sizeof (struct ReadLevel
));
351 curr
= (struct ReadLevel
*)GetHead (list
);
354 FreeStruct (curr
->s
, curr
->sd
);
356 while ((curr
= (struct ReadLevel
*)RemTail (list
)))
357 FreeMem (curr
, sizeof (struct ReadLevel
));
365 #include <aros/structdesc.h>
366 #include <proto/alib.h>
385 struct Level1 ml_Level1
;
391 DOUBLE
* ml_DoublePtr
;
392 STRPTR
* ml_StringPtr
;
393 struct Level1
* ml_Level1Ptr
;
396 IPTR ByteDesc
[] = { sizeof(UBYTE
), SDM_UBYTE(0), SDM_END
};
397 IPTR WordDesc
[] = { sizeof(UWORD
), SDM_UWORD(0), SDM_END
};
398 IPTR LongDesc
[] = { sizeof(ULONG
), SDM_ULONG(0), SDM_END
};
399 IPTR FloatDesc
[] = { sizeof(FLOAT
), SDM_FLOAT(0), SDM_END
};
400 IPTR DoubleDesc
[] = { sizeof(DOUBLE
), SDM_DOUBLE(0), SDM_END
};
401 IPTR StringDesc
[] = { sizeof(STRPTR
), SDM_STRING(0), SDM_END
};
403 #define O(x) offsetof(struct Level1,x)
406 sizeof (struct Level1
),
407 SDM_UBYTE(O(l1_Byte
)),
408 SDM_ULONG(O(l1_Long
)),
413 #define O(x) offsetof(struct MainLevel,x)
416 sizeof (struct MainLevel
),
417 SDM_UBYTE(O(ml_Byte
)),
418 SDM_UBYTE(O(ml_UByte
)),
419 SDM_UWORD(O(ml_Word
)),
420 SDM_UWORD(O(ml_UWord
)),
421 SDM_ULONG(O(ml_Long
)),
422 SDM_ULONG(O(ml_ULong
)),
423 SDM_FLOAT(O(ml_Float
)),
424 SDM_DOUBLE(O(ml_Double
)),
425 SDM_STRING(O(ml_String
)),
426 SDM_STRUCT(O(ml_Level1
),Level1Desc
),
428 SDM_PTR(O(ml_BytePtr
),ByteDesc
),
429 SDM_PTR(O(ml_WordPtr
),WordDesc
),
430 SDM_PTR(O(ml_LongPtr
),LongDesc
),
431 SDM_PTR(O(ml_FloatPtr
),FloatDesc
),
432 SDM_PTR(O(ml_DoublePtr
),DoubleDesc
),
433 SDM_PTR(O(ml_StringPtr
),StringDesc
),
434 SDM_PTR(O(ml_Level1Ptr
),Level1Desc
),
439 LONG
dosstreamhook (struct Hook
* hook
, BPTR fh
, ULONG
* msg
);
443 { NULL
, NULL
}, HookEntry
, (void *)dosstreamhook
, NULL
446 LONG
dosstreamhook (struct Hook
* hook
, BPTR fh
, ULONG
* msg
)
457 rc
= FPutC (fh
, ((struct BEIOM_Write
*)msg
)->Data
);
463 rc
= Seek (fh
, ((struct BEIOM_Ignore
*)msg
)->Count
, OFFSET_CURRENT
);
469 } /* dosstreamhook */
471 int main (int argc
, char ** argv
)
473 struct MainLevel demo
=
476 (WORD
)0x8844, 0xFF77,
477 (LONG
)0x88442211, 0xFF773311,
480 { (BYTE
)0x88, (LONG
)0x88442211 },
484 WORD w
= (WORD
)0x8844;
485 LONG l
= (LONG
)0x88442211;
491 (BYTE
)0x88, (LONG
)0x88442211
494 struct MainLevel
* readback
;
496 demo
.ml_BytePtr
= &b
;
497 demo
.ml_WordPtr
= &w
;
498 demo
.ml_LongPtr
= &l
;
499 demo
.ml_FloatPtr
= &f
;
500 demo
.ml_DoublePtr
= &d
;
501 demo
.ml_StringPtr
= &s
;
502 demo
.ml_Level1Ptr
= &l1
;
504 fh
= Open ("writestruct.dat", MODE_NEWFILE
);
508 PrintFault (IoErr(), "Can't open file\n");
513 This writes the following data stream:
519 0006 88 44 22 11 ml_Long
520 000a ff 77 33 11 ml_ULong
521 000e 3f c0 00 00 ml_Float
522 0012 3f fc 00 00 00 00 00 00 ml_Double
523 001a 01:48 61 6c 6c 6f 00 ml_String
524 0021 88 ml_Level1.l1_Byte
525 0022 88 44 22 11 ml_Level1.l1_Long
526 0026 01:88 ml_BytePtr
527 0028 01:88 44 ml_WordPtr
528 002b 01:88 44 22 11 ml_LongPtr
529 0030 01:3f c0 00 00 ml_FloatPtr
530 0035 01:3f fc 00 00 00 00 00 00 ml_DoublePtr
531 003e 01:01:48 61 6c 6c 6f 00 ml_StringPtr - Note two 01 !
532 0046 01:88 88 44 22 11 ml_Level1Ptr
535 if (!WriteStruct (&dsh
, &demo
, fh
, MainDesc
))
537 PrintFault (IoErr(), "Failed to write to file\n");
542 PrintFault (IoErr(), "Failed to close file\n");
545 /* Read the structure back */
546 fh
= Open ("writestruct.dat", MODE_OLDFILE
);
550 PrintFault (IoErr(), "Can't open file for reading\n");
554 if (!ReadStruct (&dsh
, (APTR
*)&readback
, fh
, MainDesc
))
556 PrintFault (IoErr(), "Failed to read from file\n");
563 ptr
= (UBYTE
*)readback
;
566 kprintf ("readback = %p\n", readback
);
568 kprintf ("%02X (88) %02X (FF)\n"
569 , (UBYTE
)readback
->ml_Byte
572 kprintf ("%04X (8844) %04X (FF77)\n"
573 , (UWORD
)readback
->ml_Word
576 kprintf ("%08lX (88442211) %08lX (FF773311)\n"
580 kprintf ("%08lX (3FC00000) %08lX:%08lX (3FFC0000:00000000)\n"
581 , *(ULONG
*)&readback
->ml_Float
582 , ((ULONG
*)&readback
->ml_Double
)[1]
583 , ((ULONG
*)&readback
->ml_Double
)[0]
585 kprintf ("%s (Hallo)\n"
586 , readback
->ml_String
588 kprintf ("{ %02X %08X } ({ 88 88442211 })\n"
589 , (UBYTE
)readback
->ml_Level1
.l1_Byte
590 , readback
->ml_Level1
.l1_Long
592 kprintf ("%02X (88)\n"
593 , (UBYTE
)*readback
->ml_BytePtr
595 kprintf ("%04X (8844)\n"
596 , (UWORD
)*readback
->ml_WordPtr
598 kprintf ("%08lX (88442211)\n"
599 , *readback
->ml_LongPtr
601 kprintf ("%08lX (3FC00000) %08lX:%08lX (3FFC0000:00000000)\n"
602 , *(ULONG
*)readback
->ml_FloatPtr
603 , ((ULONG
*)readback
->ml_DoublePtr
)[1]
604 , ((ULONG
*)readback
->ml_DoublePtr
)[0]
606 kprintf ("%s (Hallo)\n"
607 , *readback
->ml_StringPtr
609 kprintf ("{ %02X %08X } ({ 88 88442211 })\n"
610 , (UBYTE
)readback
->ml_Level1Ptr
->l1_Byte
611 , readback
->ml_Level1Ptr
->l1_Long
614 FreeStruct (readback
, MainDesc
);
619 PrintFault (IoErr(), "Failed to close file after reading\n");