comp.lang.ada
 help / color / mirror / Atom feed
From: Richard D Riehle <laoXhai@ix.netcom.com>
Subject: Re: Ada.Streams examples
Date: 1999/03/12
Date: 1999-03-11T18:51:11-06:00	[thread overview]
Message-ID: <7c9odv$2am@dfw-ixnews4.ix.netcom.com> (raw)
In-Reply-To: 36E82E5B.6C1B4050@nospam.lmco.com

In article <36E82E5B.6C1B4050@nospam.lmco.com>,
	Steve Quinlan <steven.quinlan@nospam.lmco.com> wrote:

>  OK, that's clearer. I understand that when you define a new stream type
>derived from root_stream_class you have to implement the read and write
>procedures that override Ada.Streams. But what GNAT did was to override the
>'read and 'write attributes.

 That is exactly right.  Notice how the overriding was done.  First
 the author coded an procedure specification,

 procedure Exception_Occurrence_Read
     (Stream : access Ada.Streams.Root_Stream_Type'Class;
      Item   : out Exception_Occurrence);

 The she/he attached that procedure to the 'Read attribute.  

for Exception_Occurrence'Read  use Exception_Occurrence_Read;

 This means that there is now a special version of 'Read for
 Exception_Occurrence.  This is important because the author 
 wanted 'Read to behave in a very special way.  The final code
 for implementing the procedure looks like this,

procedure Exception_Occurrence_Read
				(Stream : access Ada.Streams.Root_Stream_Type'Class;
				 Item   : out    Exception_Occurrence) is
	Name : String       := String'Input(Stream);
	Len  : Natural      := Natural'Input(Stream);
	Msg  : String       := String'Input(Stream);
begin
  Item.Id := Exception_Id (Internal_Exception (Name));
	if Msg'Length /= Len then
     raise Data_Error;
  end if;
      --  Silently truncate message if it does not fit
	Item.Msg_Length := Natural'Min (Len, Item.Max_Length);
	Item.Msg (1 .. Item.Msg_Length) := Msg (1 .. Item.Msg_Length);
end Exception_Occurrence_Read;

This version will behave as one would expect for the data type.  This
one reason why Ada.Streams is important: so the designer can create
well-behaved 'Read and 'Write attributes for composite data types.
Imagine, for example, that you wanted a 'Read and 'Write for a
full data structure such as a stack.  You would certainly want to code
your own version of those attributes.  It would be a far more complex
procedure than the ones we have looked at so far.  But it would be 
possible if you wanted to take the trouble.

As another simpler example, we override the abstract Read for a
brand new type,

with Ada.Streams;
package Stream_05 is

  type My_Stream is tagged record
     Id  : Natural := 0;
  end record;
  
  procedure My_Stream_Read 
      (Stream : access Ada.Streams.Root_Stream_Type'Class;
       Item   : out My_Stream);
       
  for My_Stream'Read use My_Stream_Read;
  
  -- also override Write for a complete implementation  

end Stream_05;

The coding of My_Stream_Read is left as an excercise. You may follow the
pattern shown in the Exception_Occurrence example. Now we create a little
test program.  

with Stream_05;                                    --  1
with Ada.Streams.Stream_IO;                        --  2
use  Ada;                                          --  3
procedure Test_Stream_05 is                        --  4
  The_Stream : Streams.Stream_IO.Stream_Access;    --  5
  Data : Stream_05.My_Stream;                      --  6
  Class_Data : Stream_IO.My_Stream'Class := Data;  --  7
begin                                              --  8
  -- First version for overriding Read             --  9
  Data := Stream_05.My_Stream'Input(The_Stream);   -- 10 
  -- Second version of using the Read              -- 11
  Stream_05.My_Stream'Read(The_Stream, Data);      -- 12
    -- Third version of using the Read             -- 13
  Class_Data := Stream_05.                         -- 14
                My_Stream'Class'Input(The_Stream); -- 15
end Test_Stream_05;                                -- 16

The first version, on line 10, shows how we can use this
with the 'Input statement.   The version on line 12 shows
how we use it with a 'Read statement.   The version on lines
14-15 show how to call it with a 'Class'Input.  Note that 
the 'Class'Input version reads the tag and is dispatching.

The rules for each type of call are clearly spelled out in
ALRM 13.13.2.  Congratualtions to whoever wrote that section
of the ALRM.  They did a good job of explaining the mechanism.

Richard Riehle
richard@adaworks.com
http://www.adaworks.com




      reply	other threads:[~1999-03-12  0:00 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-03-10  0:00 Ada.Streams examples Tom Moran
1999-03-10  0:00 ` Steve Quinlan
1999-03-10  0:00 ` dennison
1999-03-10  0:00   ` Rex Reges
1999-03-10  0:00     ` dennison
     [not found]       ` <36E7036B.EADEEA80@Boeing.com>
1999-03-11  0:00         ` dennison
1999-03-10  0:00   ` Tom Moran
1999-03-10  0:00     ` dennison
1999-03-10  0:00       ` Tom Moran
1999-03-11  0:00         ` dennison
1999-03-17  0:00           ` Tom Moran
1999-03-11  0:00     ` Richard D Riehle
1999-03-11  0:00       ` Steve Quinlan
1999-03-11  0:00         ` Richard D Riehle
1999-03-11  0:00           ` Steve Quinlan
1999-03-12  0:00             ` Richard D Riehle [this message]
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox