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=0.6 required=5.0 tests=BAYES_00,DEAR_SOMETHING, 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: Rex Reges Subject: Re: Ada.Streams examples Date: 1999/03/10 Message-ID: <36E6C291.F97766CB@Boeing.com>#1/1 X-Deja-AN: 453508354 Content-Transfer-Encoding: 7bit Sender: nntp@news.boeing.com (Boeing NNTP News Access) X-Nntp-Posting-Host: narn.ds.boeing.com References: <36e61db4.50430543@news.pacbell.net> <7c64kl$r8s$1@nnrp1.dejanews.com> Content-Type: text/plain; charset=us-ascii Organization: AWACS Software Mime-Version: 1.0 Newsgroups: comp.lang.ada Date: 1999-03-10T00:00:00+00:00 List-Id: dennison@telepath.com wrote: > In article <36e61db4.50430543@news.pacbell.net>, > tmoran@bix.com (Tom Moran) wrote: > > Could someone please point me to a text or tutorial or something on > > using Ada.Streams - in particular overriding the default 'Read etc. > > > > Cohen's latest edition of Ada as a Second Language goes over it. > > Basicly, you just declare a read routine with the following spec: > > procedure Read > (Stream : access Ada.Streams.Root_Stream_Type'Class; > Item : out Instance > ); > > where "Instance" is your type, in the same package spec that the type > ("Instance in the above case) is declared. Then, after the full declaration > of the type you put the following line: > > for Instance'Read use Read; > > For the body of Read, you can call the 'Read method for the relevant field > types yourself. > > Another option is to read in a properly sized Ada.Streams.Stream_Element_Array > using the stream's Read method then use Unchecked_Conversion to convert the > array type(s) you need. For instance: > > Bytes_Per_Element : constant := (Ada.Streams.Stream_Element'Size + 7) / 8; > Bytes_Per_Instance : constant Natural := (Instance'Size + 7) / 8; > > Elements_Per_Header : constant Ada.Streams.Stream_Element_Offset := > Ada.Streams.Stream_Element_Offset( > (Bytes_Per_Instance + (Bytes_Per_Element - 1)) / Bytes_Per_Element); > subtype Header_Array is Ada.Streams.Stream_Element_Array (1 .. > Elements_Per_Header); > > function To_Instance is new Unchecked_Conversion > (Source => Header_Array, > Target => Instance); > > procedure Read > (Stream : access Ada.Streams.Root_Stream_Type'Class; > Item : out Instance > ) is > > Trash : Ada.Streams.Stream_Element_Offset; > Item_Elements : Header_Array; > begin > > Ada.Streams.Read > (Stream => Stream.all, > Item => Item_Elements, > Last => Trash > ); > > Item := To_Instance (Item_Elements); > > end Read; > > A wise developer would probably check "Trash". But in my case I happen to > know (because I wrote them) that the streams used for this call will raise > exceptions rather than return a different Last than Item_Elements'Last. > > If there's anything else you are curious about, just ask. > > T.E.D. Stream_IO solved the File IO difficulties that were in Ada 83. In Ada 83, the elements put into a file were of some discriminated record. This made it necessary to have a huge structure to define all the possible things that one might want to put in the file. Stream_IO allows one to stuff any number of items of varying type into a file as long as the user keeps track of this information when the file is to be read again. I would like to use Streams to create a similar package to Stream_IO, but write to a memory object. If I have a "storage container", how can I fill it with objects of varying types? How would I use Streams to do this? Say I have container defined as follows: subtype Storage_Container is Streams.Stream_Element_Array ; type Medium_Storage_Container is Storage_Container( 0..511) ; I'ld like to be able to code something like this: Parcel : Medium_Storage_Container ; Parcel_Access : Container_Access ; Parcel_Access := Start_Packing( Container => Parcel ); String'Write ( Parcel_Access, "Dear Sir, The items you ordered." ); Integer'Write( Parcel_Access, 2 ); Gadget'Write ( Parcel_Access, New_Gadget ); Widget'Write ( Parcel_Access, New_Widget ); Stop_Packing( Container => Parcel ); The final step is to hand this Parcel off to a delivery service for shipping. The delivery service doesn't care what's in the parcel, only what the size and destination are. I'm sure it must be easy to code this using Streams, but even with the ARM and the Barnes book, I don't have a clear picture of what I need to do. Rex Reges