2 Copyright © 1995-2017, 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. If NULL, a new memory block is allocated
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
;
74 BOOL pre_alloc
= (*dataptr
) ? TRUE
: FALSE
;
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 ++]
97 if (!curr
->s
&& !(curr
->s
= AllocMem (size
, MEMF_CLEAR
)) )
106 case SDT_UBYTE
: /* Read one 8bit byte */
107 if (!ReadByte (hook
, (UBYTE
*)(curr
->s
+ IDESC
), stream
))
112 case SDT_UWORD
: /* Read one 16bit word */
113 if (!ReadWord (hook
, (UWORD
*)(curr
->s
+ IDESC
), stream
))
118 case SDT_ULONG
: /* Read one 32bit long */
119 if (!ReadLong (hook
, (ULONG
*)(curr
->s
+ IDESC
), stream
))
124 case SDT_FLOAT
: /* Read one 32bit IEEE */
125 if (!ReadFloat (hook
, (FLOAT
*)(curr
->s
+ IDESC
), stream
))
130 case SDT_DOUBLE
: /* Read one 64bit IEEE */
131 if (!ReadDouble (hook
, (DOUBLE
*)(curr
->s
+ IDESC
), stream
))
136 case SDT_COPY
: { /* Copy 'n' bytes */
137 int i
, count
, offset
;
142 for (i
= 0; i
< count
; i
++)
144 if (!ReadByte (hook
, (UBYTE
*)(curr
->s
+ offset
+ i
), stream
))
150 case SDT_STRING
: { /* Read a string */
154 sptr
= (STRPTR
*)(curr
->s
+ IDESC
);
156 if (!ReadByte (hook
, &valid_ptr
, stream
))
161 if (!ReadString (hook
, sptr
, stream
))
171 case SDT_STRUCT
: { /* Read a structure */
172 struct ReadLevel
* next
;
176 aptr
= (APTR
)(curr
->s
+ IDESC
);
177 desc
= (IPTR
*)IDESC
;
179 curr
->pos
-= 3; /* Go back to type */
181 if (!(next
= AllocMem (sizeof (struct ReadLevel
), MEMF_ANY
)) )
184 AddTail (list
, (struct Node
*)next
);
193 case SDT_PTR
: { /* Follow a pointer */
194 struct ReadLevel
* next
;
200 aptr
= ((APTR
*)(curr
->s
+ IDESC
));
201 desc
= (IPTR
*)IDESC
;
203 if (!ReadByte (hook
, &valid_ptr
, stream
))
210 if (!(next
= AllocMem (sizeof (struct ReadLevel
), MEMF_ANY
)) )
213 AddTail (list
, (struct Node
*)next
);
226 case SDT_IGNORE
: { /* Ignore x bytes */
227 struct BEIOM_Ignore ig
= {BEIO_IGNORE
, IDESC
};
228 if (CallHookA (hook
, stream
, &ig
) == EOF
)
233 case SDT_FILL_BYTE
: { /* Fill x bytes */
242 memset (curr
->s
+ offset
, value
, count
);
246 case SDT_FILL_LONG
: { /* Fill x longs */
251 ulptr
= (ULONG
*)(curr
->s
+ IDESC
);
260 case SDT_IFILL_BYTE
: { /* Fill x bytes */
269 struct BEIOM_Ignore ig
= {BEIO_IGNORE
, count
};
271 if (CallHookA (hook
, stream
, &ig
) == EOF
)
274 memset (curr
->s
+ offset
, value
, count
);
278 case SDT_IFILL_LONG
: { /* Fill x longs */
283 ulptr
= (ULONG
*)(curr
->s
+ IDESC
);
287 struct BEIOM_Ignore ig
= {BEIO_IGNORE
, count
<< 2};
289 if (CallHookA (hook
, stream
, &ig
) == EOF
)
297 case SDT_SPECIAL
: { /* Call user hook */
301 data
.sdd_Dest
= ((APTR
)(curr
->s
+ IDESC
));
302 data
.sdd_Mode
= SDV_SPECIALMODE_READ
;
303 data
.sdd_Stream
= stream
;
305 uhook
= (struct Hook
*)IDESC
;
307 if (!CallHookA (uhook
, hook
, &data
))
317 /* End of the description list ? */
320 struct ReadLevel
* last
;
322 /* Remove the current level */
324 Remove ((struct Node
*)last
);
326 /* Get the last level */
327 if ((curr
= (struct ReadLevel
*)GetTail (list
)))
332 curr
->pos
+= 2; /* Skip 2 parameters */
338 aptr
= ((APTR
*)(curr
->s
+ IDESC
));
339 curr
->pos
++; /* Skip description parameter */
342 Now put the result of the current level in the
343 struct of the previous level.
351 FreeMem (last
, sizeof (struct ReadLevel
));
362 FreeMem (curr
, sizeof (struct ReadLevel
));
367 curr
= (struct ReadLevel
*)GetHead (list
);
369 if (curr
&& curr
->s
&& !pre_alloc
)
370 FreeStruct (curr
->s
, curr
->sd
);
372 while ((curr
= (struct ReadLevel
*)RemTail (list
)))
373 FreeMem (curr
, sizeof (struct ReadLevel
));
381 #include <aros/structdesc.h>
382 #include <proto/alib.h>
401 struct Level1 ml_Level1
;
407 DOUBLE
* ml_DoublePtr
;
408 STRPTR
* ml_StringPtr
;
409 struct Level1
* ml_Level1Ptr
;
412 IPTR ByteDesc
[] = { sizeof(UBYTE
), SDM_UBYTE(0), SDM_END
};
413 IPTR WordDesc
[] = { sizeof(UWORD
), SDM_UWORD(0), SDM_END
};
414 IPTR LongDesc
[] = { sizeof(ULONG
), SDM_ULONG(0), SDM_END
};
415 IPTR FloatDesc
[] = { sizeof(FLOAT
), SDM_FLOAT(0), SDM_END
};
416 IPTR DoubleDesc
[] = { sizeof(DOUBLE
), SDM_DOUBLE(0), SDM_END
};
417 IPTR StringDesc
[] = { sizeof(STRPTR
), SDM_STRING(0), SDM_END
};
419 #define O(x) offsetof(struct Level1,x)
422 sizeof (struct Level1
),
423 SDM_UBYTE(O(l1_Byte
)),
424 SDM_ULONG(O(l1_Long
)),
429 #define O(x) offsetof(struct MainLevel,x)
432 sizeof (struct MainLevel
),
433 SDM_UBYTE(O(ml_Byte
)),
434 SDM_UBYTE(O(ml_UByte
)),
435 SDM_UWORD(O(ml_Word
)),
436 SDM_UWORD(O(ml_UWord
)),
437 SDM_ULONG(O(ml_Long
)),
438 SDM_ULONG(O(ml_ULong
)),
439 SDM_FLOAT(O(ml_Float
)),
440 SDM_DOUBLE(O(ml_Double
)),
441 SDM_STRING(O(ml_String
)),
442 SDM_STRUCT(O(ml_Level1
),Level1Desc
),
444 SDM_PTR(O(ml_BytePtr
),ByteDesc
),
445 SDM_PTR(O(ml_WordPtr
),WordDesc
),
446 SDM_PTR(O(ml_LongPtr
),LongDesc
),
447 SDM_PTR(O(ml_FloatPtr
),FloatDesc
),
448 SDM_PTR(O(ml_DoublePtr
),DoubleDesc
),
449 SDM_PTR(O(ml_StringPtr
),StringDesc
),
450 SDM_PTR(O(ml_Level1Ptr
),Level1Desc
),
455 LONG
dosstreamhook (struct Hook
* hook
, BPTR fh
, ULONG
* msg
);
459 { NULL
, NULL
}, HookEntry
, (void *)dosstreamhook
, NULL
462 LONG
dosstreamhook (struct Hook
* hook
, BPTR fh
, ULONG
* msg
)
473 rc
= FPutC (fh
, ((struct BEIOM_Write
*)msg
)->Data
);
479 rc
= Seek (fh
, ((struct BEIOM_Ignore
*)msg
)->Count
, OFFSET_CURRENT
);
485 } /* dosstreamhook */
487 int main (int argc
, char ** argv
)
489 struct MainLevel demo
=
492 (WORD
)0x8844, 0xFF77,
493 (LONG
)0x88442211, 0xFF773311,
496 { (BYTE
)0x88, (LONG
)0x88442211 },
500 WORD w
= (WORD
)0x8844;
501 LONG l
= (LONG
)0x88442211;
507 (BYTE
)0x88, (LONG
)0x88442211
510 struct MainLevel
* readback
;
512 demo
.ml_BytePtr
= &b
;
513 demo
.ml_WordPtr
= &w
;
514 demo
.ml_LongPtr
= &l
;
515 demo
.ml_FloatPtr
= &f
;
516 demo
.ml_DoublePtr
= &d
;
517 demo
.ml_StringPtr
= &s
;
518 demo
.ml_Level1Ptr
= &l1
;
520 fh
= Open ("writestruct.dat", MODE_NEWFILE
);
524 PrintFault (IoErr(), "Can't open file\n");
529 This writes the following data stream:
535 0006 88 44 22 11 ml_Long
536 000a ff 77 33 11 ml_ULong
537 000e 3f c0 00 00 ml_Float
538 0012 3f fc 00 00 00 00 00 00 ml_Double
539 001a 01:48 61 6c 6c 6f 00 ml_String
540 0021 88 ml_Level1.l1_Byte
541 0022 88 44 22 11 ml_Level1.l1_Long
542 0026 01:88 ml_BytePtr
543 0028 01:88 44 ml_WordPtr
544 002b 01:88 44 22 11 ml_LongPtr
545 0030 01:3f c0 00 00 ml_FloatPtr
546 0035 01:3f fc 00 00 00 00 00 00 ml_DoublePtr
547 003e 01:01:48 61 6c 6c 6f 00 ml_StringPtr - Note two 01 !
548 0046 01:88 88 44 22 11 ml_Level1Ptr
551 if (!WriteStruct (&dsh
, &demo
, fh
, MainDesc
))
553 PrintFault (IoErr(), "Failed to write to file\n");
558 PrintFault (IoErr(), "Failed to close file\n");
561 /* Read the structure back */
562 fh
= Open ("writestruct.dat", MODE_OLDFILE
);
566 PrintFault (IoErr(), "Can't open file for reading\n");
570 if (!ReadStruct (&dsh
, (APTR
*)&readback
, fh
, MainDesc
))
572 PrintFault (IoErr(), "Failed to read from file\n");
579 ptr
= (UBYTE
*)readback
;
582 kprintf ("readback = %p\n", readback
);
584 kprintf ("%02X (88) %02X (FF)\n"
585 , (UBYTE
)readback
->ml_Byte
588 kprintf ("%04X (8844) %04X (FF77)\n"
589 , (UWORD
)readback
->ml_Word
592 kprintf ("%08lX (88442211) %08lX (FF773311)\n"
596 kprintf ("%08lX (3FC00000) %08lX:%08lX (3FFC0000:00000000)\n"
597 , *(ULONG
*)&readback
->ml_Float
598 , ((ULONG
*)&readback
->ml_Double
)[1]
599 , ((ULONG
*)&readback
->ml_Double
)[0]
601 kprintf ("%s (Hallo)\n"
602 , readback
->ml_String
604 kprintf ("{ %02X %08X } ({ 88 88442211 })\n"
605 , (UBYTE
)readback
->ml_Level1
.l1_Byte
606 , readback
->ml_Level1
.l1_Long
608 kprintf ("%02X (88)\n"
609 , (UBYTE
)*readback
->ml_BytePtr
611 kprintf ("%04X (8844)\n"
612 , (UWORD
)*readback
->ml_WordPtr
614 kprintf ("%08lX (88442211)\n"
615 , *readback
->ml_LongPtr
617 kprintf ("%08lX (3FC00000) %08lX:%08lX (3FFC0000:00000000)\n"
618 , *(ULONG
*)readback
->ml_FloatPtr
619 , ((ULONG
*)readback
->ml_DoublePtr
)[1]
620 , ((ULONG
*)readback
->ml_DoublePtr
)[0]
622 kprintf ("%s (Hallo)\n"
623 , *readback
->ml_StringPtr
625 kprintf ("{ %02X %08X } ({ 88 88442211 })\n"
626 , (UBYTE
)readback
->ml_Level1Ptr
->l1_Byte
627 , readback
->ml_Level1Ptr
->l1_Long
630 FreeStruct (readback
, MainDesc
);
635 PrintFault (IoErr(), "Failed to close file after reading\n");