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. 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_STRING
: { /* Read a string */
140 sptr
= (STRPTR
*)(curr
->s
+ IDESC
);
142 if (!ReadByte (hook
, &valid_ptr
, stream
))
147 if (!ReadString (hook
, sptr
, stream
))
157 case SDT_STRUCT
: { /* Read a structure */
158 struct ReadLevel
* next
;
162 aptr
= (APTR
)(curr
->s
+ IDESC
);
163 desc
= (IPTR
*)IDESC
;
165 curr
->pos
-= 3; /* Go back to type */
167 if (!(next
= AllocMem (sizeof (struct ReadLevel
), MEMF_ANY
)) )
170 AddTail (list
, (struct Node
*)next
);
179 case SDT_PTR
: { /* Follow a pointer */
180 struct ReadLevel
* next
;
186 aptr
= ((APTR
*)(curr
->s
+ IDESC
));
187 desc
= (IPTR
*)IDESC
;
189 if (!ReadByte (hook
, &valid_ptr
, stream
))
196 if (!(next
= AllocMem (sizeof (struct ReadLevel
), MEMF_ANY
)) )
199 AddTail (list
, (struct Node
*)next
);
212 case SDT_IGNORE
: { /* Ignore x bytes */
213 struct BEIOM_Ignore ig
= {BEIO_IGNORE
, IDESC
};
214 if (CallHookA (hook
, stream
, &ig
) == EOF
)
219 case SDT_FILL_BYTE
: { /* Fill x bytes */
228 memset (curr
->s
+ offset
, value
, count
);
232 case SDT_FILL_LONG
: { /* Fill x longs */
237 ulptr
= (ULONG
*)(curr
->s
+ IDESC
);
246 case SDT_IFILL_BYTE
: { /* Fill x bytes */
255 struct BEIOM_Ignore ig
= {BEIO_IGNORE
, count
};
257 if (CallHookA (hook
, stream
, &ig
) == EOF
)
260 memset (curr
->s
+ offset
, value
, count
);
264 case SDT_IFILL_LONG
: { /* Fill x longs */
269 ulptr
= (ULONG
*)(curr
->s
+ IDESC
);
273 struct BEIOM_Ignore ig
= {BEIO_IGNORE
, count
<< 2};
275 if (CallHookA (hook
, stream
, &ig
) == EOF
)
283 case SDT_SPECIAL
: { /* Call user hook */
287 data
.sdd_Dest
= ((APTR
)(curr
->s
+ IDESC
));
288 data
.sdd_Mode
= SDV_SPECIALMODE_READ
;
289 data
.sdd_Stream
= stream
;
291 uhook
= (struct Hook
*)IDESC
;
293 if (!CallHookA (uhook
, hook
, &data
))
303 /* End of the description list ? */
306 struct ReadLevel
* last
;
308 /* Remove the current level */
310 Remove ((struct Node
*)last
);
312 /* Get the last level */
313 if ((curr
= (struct ReadLevel
*)GetTail (list
)))
318 curr
->pos
+= 2; /* Skip 2 parameters */
324 aptr
= ((APTR
*)(curr
->s
+ IDESC
));
325 curr
->pos
++; /* Skip description parameter */
328 Now put the result of the current level in the
329 struct of the previous level.
337 FreeMem (last
, sizeof (struct ReadLevel
));
348 FreeMem (curr
, sizeof (struct ReadLevel
));
353 curr
= (struct ReadLevel
*)GetHead (list
);
355 if (curr
&& curr
->s
&& !pre_alloc
)
356 FreeStruct (curr
->s
, curr
->sd
);
358 while ((curr
= (struct ReadLevel
*)RemTail (list
)))
359 FreeMem (curr
, sizeof (struct ReadLevel
));
367 #include <aros/structdesc.h>
368 #include <proto/alib.h>
387 struct Level1 ml_Level1
;
393 DOUBLE
* ml_DoublePtr
;
394 STRPTR
* ml_StringPtr
;
395 struct Level1
* ml_Level1Ptr
;
398 IPTR ByteDesc
[] = { sizeof(UBYTE
), SDM_UBYTE(0), SDM_END
};
399 IPTR WordDesc
[] = { sizeof(UWORD
), SDM_UWORD(0), SDM_END
};
400 IPTR LongDesc
[] = { sizeof(ULONG
), SDM_ULONG(0), SDM_END
};
401 IPTR FloatDesc
[] = { sizeof(FLOAT
), SDM_FLOAT(0), SDM_END
};
402 IPTR DoubleDesc
[] = { sizeof(DOUBLE
), SDM_DOUBLE(0), SDM_END
};
403 IPTR StringDesc
[] = { sizeof(STRPTR
), SDM_STRING(0), SDM_END
};
405 #define O(x) offsetof(struct Level1,x)
408 sizeof (struct Level1
),
409 SDM_UBYTE(O(l1_Byte
)),
410 SDM_ULONG(O(l1_Long
)),
415 #define O(x) offsetof(struct MainLevel,x)
418 sizeof (struct MainLevel
),
419 SDM_UBYTE(O(ml_Byte
)),
420 SDM_UBYTE(O(ml_UByte
)),
421 SDM_UWORD(O(ml_Word
)),
422 SDM_UWORD(O(ml_UWord
)),
423 SDM_ULONG(O(ml_Long
)),
424 SDM_ULONG(O(ml_ULong
)),
425 SDM_FLOAT(O(ml_Float
)),
426 SDM_DOUBLE(O(ml_Double
)),
427 SDM_STRING(O(ml_String
)),
428 SDM_STRUCT(O(ml_Level1
),Level1Desc
),
430 SDM_PTR(O(ml_BytePtr
),ByteDesc
),
431 SDM_PTR(O(ml_WordPtr
),WordDesc
),
432 SDM_PTR(O(ml_LongPtr
),LongDesc
),
433 SDM_PTR(O(ml_FloatPtr
),FloatDesc
),
434 SDM_PTR(O(ml_DoublePtr
),DoubleDesc
),
435 SDM_PTR(O(ml_StringPtr
),StringDesc
),
436 SDM_PTR(O(ml_Level1Ptr
),Level1Desc
),
441 LONG
dosstreamhook (struct Hook
* hook
, BPTR fh
, ULONG
* msg
);
445 { NULL
, NULL
}, HookEntry
, (void *)dosstreamhook
, NULL
448 LONG
dosstreamhook (struct Hook
* hook
, BPTR fh
, ULONG
* msg
)
459 rc
= FPutC (fh
, ((struct BEIOM_Write
*)msg
)->Data
);
465 rc
= Seek (fh
, ((struct BEIOM_Ignore
*)msg
)->Count
, OFFSET_CURRENT
);
471 } /* dosstreamhook */
473 int main (int argc
, char ** argv
)
475 struct MainLevel demo
=
478 (WORD
)0x8844, 0xFF77,
479 (LONG
)0x88442211, 0xFF773311,
482 { (BYTE
)0x88, (LONG
)0x88442211 },
486 WORD w
= (WORD
)0x8844;
487 LONG l
= (LONG
)0x88442211;
493 (BYTE
)0x88, (LONG
)0x88442211
496 struct MainLevel
* readback
;
498 demo
.ml_BytePtr
= &b
;
499 demo
.ml_WordPtr
= &w
;
500 demo
.ml_LongPtr
= &l
;
501 demo
.ml_FloatPtr
= &f
;
502 demo
.ml_DoublePtr
= &d
;
503 demo
.ml_StringPtr
= &s
;
504 demo
.ml_Level1Ptr
= &l1
;
506 fh
= Open ("writestruct.dat", MODE_NEWFILE
);
510 PrintFault (IoErr(), "Can't open file\n");
515 This writes the following data stream:
521 0006 88 44 22 11 ml_Long
522 000a ff 77 33 11 ml_ULong
523 000e 3f c0 00 00 ml_Float
524 0012 3f fc 00 00 00 00 00 00 ml_Double
525 001a 01:48 61 6c 6c 6f 00 ml_String
526 0021 88 ml_Level1.l1_Byte
527 0022 88 44 22 11 ml_Level1.l1_Long
528 0026 01:88 ml_BytePtr
529 0028 01:88 44 ml_WordPtr
530 002b 01:88 44 22 11 ml_LongPtr
531 0030 01:3f c0 00 00 ml_FloatPtr
532 0035 01:3f fc 00 00 00 00 00 00 ml_DoublePtr
533 003e 01:01:48 61 6c 6c 6f 00 ml_StringPtr - Note two 01 !
534 0046 01:88 88 44 22 11 ml_Level1Ptr
537 if (!WriteStruct (&dsh
, &demo
, fh
, MainDesc
))
539 PrintFault (IoErr(), "Failed to write to file\n");
544 PrintFault (IoErr(), "Failed to close file\n");
547 /* Read the structure back */
548 fh
= Open ("writestruct.dat", MODE_OLDFILE
);
552 PrintFault (IoErr(), "Can't open file for reading\n");
556 if (!ReadStruct (&dsh
, (APTR
*)&readback
, fh
, MainDesc
))
558 PrintFault (IoErr(), "Failed to read from file\n");
565 ptr
= (UBYTE
*)readback
;
568 kprintf ("readback = %p\n", readback
);
570 kprintf ("%02X (88) %02X (FF)\n"
571 , (UBYTE
)readback
->ml_Byte
574 kprintf ("%04X (8844) %04X (FF77)\n"
575 , (UWORD
)readback
->ml_Word
578 kprintf ("%08lX (88442211) %08lX (FF773311)\n"
582 kprintf ("%08lX (3FC00000) %08lX:%08lX (3FFC0000:00000000)\n"
583 , *(ULONG
*)&readback
->ml_Float
584 , ((ULONG
*)&readback
->ml_Double
)[1]
585 , ((ULONG
*)&readback
->ml_Double
)[0]
587 kprintf ("%s (Hallo)\n"
588 , readback
->ml_String
590 kprintf ("{ %02X %08X } ({ 88 88442211 })\n"
591 , (UBYTE
)readback
->ml_Level1
.l1_Byte
592 , readback
->ml_Level1
.l1_Long
594 kprintf ("%02X (88)\n"
595 , (UBYTE
)*readback
->ml_BytePtr
597 kprintf ("%04X (8844)\n"
598 , (UWORD
)*readback
->ml_WordPtr
600 kprintf ("%08lX (88442211)\n"
601 , *readback
->ml_LongPtr
603 kprintf ("%08lX (3FC00000) %08lX:%08lX (3FFC0000:00000000)\n"
604 , *(ULONG
*)readback
->ml_FloatPtr
605 , ((ULONG
*)readback
->ml_DoublePtr
)[1]
606 , ((ULONG
*)readback
->ml_DoublePtr
)[0]
608 kprintf ("%s (Hallo)\n"
609 , *readback
->ml_StringPtr
611 kprintf ("{ %02X %08X } ({ 88 88442211 })\n"
612 , (UBYTE
)readback
->ml_Level1Ptr
->l1_Byte
613 , readback
->ml_Level1Ptr
->l1_Long
616 FreeStruct (readback
, MainDesc
);
621 PrintFault (IoErr(), "Failed to close file after reading\n");