From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,7876e4356325725b X-Google-Attributes: gid103376,public From: Richard D Riehle Subject: Re: Ada.Streams examples Date: 1999/03/12 Message-ID: <7c9odv$2am@dfw-ixnews4.ix.netcom.com>#1/1 X-Deja-AN: 454012041 References: <36e61db4.50430543@news.pacbell.net> <7c64kl$r8s$1@nnrp1.dejanews.com> <36e6cd2c.3377267@news.pacbell.net> <7c753p$3t7@dfw-ixnews3.ix.netcom.com> <36E7EFCF.82A87270@nospam.lmco.com> <7c91k2$9fl@sjx-ixn10.ix.netcom.com> <36E82E5B.6C1B4050@nospam.lmco.com> Organization: Netcom X-NETCOM-Date: Thu Mar 11 6:51:11 PM CST 1999 Newsgroups: comp.lang.ada Date: 1999-03-11T18:51:11-06:00 List-Id: In article <36E82E5B.6C1B4050@nospam.lmco.com>, Steve Quinlan 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