From: "David C. Hoos, Sr." <david.c.hoos.sr@ada95.com>
Subject: Re: Behavior of Stream Attributes On Access Types.
Date: Wed, 12 Jun 2002 22:00:45 -0500
Date: 2002-06-12T22:00:45-05:00 [thread overview]
Message-ID: <mailman.1023937450.3797.comp.lang.ada@ada.eu.org> (raw)
In-Reply-To: ae7oo4$7ob$1@nh.pace.co.uk
----- Original Message -----
From: "Marin David Condic ]" <dont.bother.mcondic.auntie.spam@[acm.org>
Newsgroups: comp.lang.ada
To: <comp.lang.ada@ada.eu.org>
Sent: June 12, 2002 10:18 AM
Subject: Re: Behavior of Stream Attributes On Access Types.
> Yes. That was helpful. But I'm still curious about how it would be done with
> the scenario I described because I want to understand the inheritance
> issues. (I can see that it would be better to handle the access values as
> you describe, but in a more "general" sense - can you describe what happens
> with the 'Read and 'Write as we travel down the chain of inheritance?)
I don't see any "inheritance issues." The RM is quite clear as to what
happens.
Each component of an aggregate is written or read in the order in which it
is declared, using either default stream attribute for that component's type,
unless that attribute is overridden by an attribute definition clause.
If, for example, a component of a record is an array of booleans, each of
those
booleans will be written or read to or from the stream as an individual octet,
because 'read or 'write is called for each element of the array, even if the
array is packed.
If that behavior is unacceptable, then you can override the default stream
attributes for the Boolean array type. I have had to do a lot of that sort of
thing when using streams to read and write to and from a network where the
network representation is defined with components that do not begin and end on
octet boundaries.
Here is an example of a 31-bit component adjacent to a one-bit component:
type An_Hour_Fraction is
delta 3600.0 * 2.0 ** (-31) range 0.0 .. 3600.0;
for An_Hour_Fraction'Small use 3600.0 * 2.0 ** (-31);
for An_Hour_Fraction'Size use 31;
type A_Time_Stamp_Kind is (Relative, Absolute);
for A_Time_Stamp_Kind use (Relative => 0, Absolute => 1);
for A_Time_Stamp_Kind'Size use 1;
type A_Time_Stamp is
record
Seconds : An_Hour_Fraction;
Kind : A_Time_Stamp_Kind;
end record;
for A_Time_Stamp use
record
Seconds at 0 range 0 .. 30;
Kind at 0 range 31 .. 31;
end record;
for A_Time_Stamp'Size use 32;
procedure Read_Time_Stamp
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : out A_Time_Stamp);
procedure Write_Time_Stamp
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : in A_Time_Stamp);
for A_Time_Stamp'Read use Read_Time_Stamp;
for A_Time_Stamp'Write use Write_Time_Stamp;
Here are the bodies of the read and write procedures:
procedure Read_Ts is
new Byte_Ordering.Read (A_Time_Stamp);
procedure Read_Time_Stamp
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : out A_Time_Stamp) renames Read_Ts;
procedure Write_Ts is
new Byte_Ordering.Write (A_Time_Stamp);
procedure Write_Time_Stamp
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : in A_Time_Stamp) renames Write_Ts;
Here is the Byte_Ordering generic:
with Ada.Streams;
package Byte_Ordering is
generic
type Item_Type is private;
procedure Read
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : out Item_type);
generic
type Item_Type is private;
procedure Write
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : Item_type);
end Byte_Ordering;
with System;
package body Byte_Ordering is
type U8 is mod 2 ** 8;
for U8'Size use 8;
type U8_Array is array (Integer range <>) of U8;
--=======================
-- Private subprograms ==
--=======================
----------
-- Swap --
----------
procedure Swap
(The_Item : in out U8_Array)
is
The_Bytes : array (1 .. The_Item'Length) of U8;
for The_Bytes'Address use The_Item'Address;
Temp : U8;
begin
for B in 1 .. The_Bytes'Last / 2 loop
Temp := The_Bytes (B);
The_Bytes (B) := The_Bytes (The_Bytes'Last - B + 1);
The_Bytes (The_Bytes'Last - B + 1) := Temp;
end loop;
end Swap;
--======================
-- Public subprograms ==
--======================
----------
-- Read --
----------
procedure Read
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : out Item_type)
is
The_Bytes : U8_Array (1 .. Item_Type'Size / U8'Size);
for The_Bytes'Address use Item'Address;
use type System.Bit_Order;
begin
U8_Array'Read (Stream, The_Bytes);
if System.Default_Bit_Order = System.Low_Order_First then
Swap (The_Bytes);
end if;
end Read;
-----------
-- Write --
-----------
procedure Write
(Stream : access Ada.Streams.Root_Stream_Type'Class;
Item : Item_Type)
is
Item_Copy : Item_type := Item;
The_Bytes : U8_Array (1 .. Item_Type'Size / U8'Size);
for The_Bytes'Address use Item'Address;
use type System.Bit_Order;
begin
if System.Default_Bit_Order = System.Low_Order_First then
Swap (The_Bytes);
end if;
U8_Array'Write (Stream, The_Bytes);
end Write;
end Byte_Ordering;
If stream representation is important -- e.g., when it is needed to conform
to a protocol specification, or when you need to communicate between
little- and big- endian architectures, then you need to declare aggregate
types that begin and end on octet boundaries, and override their default
stream attributes.
Yes, I know that some will find fault that I used address clauses to overlay
objects instead of using unchecked conversion -- but this was done in the
interest of efficiency.
next prev parent reply other threads:[~2002-06-13 3:00 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-06-10 19:38 Behavior of Stream Attributes On Access Types Marin David Condic
2002-06-11 5:33 ` R. Tim Coslet
2002-06-11 14:15 ` Marin David Condic
2002-06-11 13:47 ` Ted Dennison
2002-06-11 14:27 ` Marin David Condic
2002-06-11 14:37 ` Marin David Condic
2002-06-12 14:19 ` David C. Hoos
2002-06-12 15:18 ` Marin David Condic
2002-06-13 3:00 ` David C. Hoos, Sr. [this message]
2002-06-14 18:27 ` Simon Wright
2002-06-14 18:53 ` Marin David Condic
2002-06-15 14:56 ` Simon Wright
2002-06-16 2:27 ` Randy Brukardt
2002-06-17 14:31 ` Marin David Condic
2002-06-18 19:30 ` Randy Brukardt
2002-06-12 19:39 ` Randy Brukardt
2002-06-12 13:31 ` Ted Dennison
2002-06-11 21:56 ` Randy Brukardt
2002-06-12 3:44 ` David C. Hoos, Sr.
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox