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.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,335f67c75a2a5d5 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2000-12-28 18:20:58 PST Path: supernews.google.com!sn-xit-02!supernews.com!216.227.56.88.MISMATCH!telocity-west!TELOCITY!enews.sgi.com!newshub2.rdc1.sfba.home.com!news.home.com!news1.rdc2.on.home.com.POSTED!not-for-mail Message-ID: <3A4BF469.1D5C04F0@home.com> From: "Warren W. Gay VE3WWG" X-Mailer: Mozilla 4.75 [en] (Windows NT 5.0; U) X-Accept-Language: en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: In Plain Text: Tags.Internal_Tag(String'Input(Stream)) ?? References: <3A4AC329.9C2A311A@home.com> <3A4B557F.F167C8E@home.com> <92fnnn$emq$1@nnrp1.deja.com> <3A4B86B4.DB440BF5@home.com> <92g57c$qgp$1@nnrp1.deja.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Date: Fri, 29 Dec 2000 02:20:57 GMT NNTP-Posting-Host: 24.141.193.52 X-Complaints-To: abuse@home.net X-Trace: news1.rdc2.on.home.com 978056457 24.141.193.52 (Thu, 28 Dec 2000 18:20:57 PST) NNTP-Posting-Date: Thu, 28 Dec 2000 18:20:57 PST Organization: Excite@Home - The Leader in Broadband http://home.com/faster Xref: supernews.google.com comp.lang.ada:3440 Date: 2000-12-29T02:20:57+00:00 List-Id: Ted Dennison wrote: > In article <3A4B86B4.DB440BF5@home.com>, > "Warren W. Gay VE3WWG" wrote: > > Ted Dennison wrote: > > > You might have better luck creating your own custom stream type for > > > WAV data. > > > > I am in the process of doing that very thing. However, I am looking > > for ways to more elegantly read in the various chunks (tagged records) > > from the stream. S'Class'Input() comes tantalizingly close. > > So you are saying that you have a nice custom stream of unstructured > data, but you don't want to be able to read (or perhaps write) just any > type of data from it in the normal way? Instead it has a strict > structure you have to adhere to, which you don't have control over? The problem (at a high level) is a simple one: I want to read in a tagged record from a stream -- which can be any one of a family of tagged records based upon some root tagged type (base class in C++ parlance). For example, I might have a header record like: type Chunk_Hdr is tagged -- Chunk_Hdr'External_Tag holds the Chunk ID record Size: Unsigned_32; end record; Then I have several other chunks, derived from it, for example: type Format_Chunk is new Chunk_Hdr with record Sample_Rate: Unsigned_32; etc. end record; for Format_Chunk'External_Tag use "fmt "; type Data_Chunk is new Chunk_Hdr with record ... end record; for Data_Chunk'External_Tag use "data"; Since WAVE chunks do not necessarily strictly obey a sequence, I need to be able to do: declare Chunk: Chunk_Hdr'Class = Chunk_Hdr'Class'Input(Stream); begin -- do stuff with Chunk The S'Class'Input() procedure first reads the tag in from the stream, and then automatically dispatches to the _correct_ Read routine to bring in the rest of the contents. The appropriate tagged record is returned and assigned to Chunk. This works elegantly as designed, if you are reading back data created by S'Classs'Output() in Ada. So the problem is that now I want to bend the Ada defaults so that the Chunk ID is interpreted as an external Tag for the class of tagged records I expect to encounter. I can set the external representation of the tags to match the Microsoft chunk ID's. The real problem is that I have to bend the tag reading procedure such that it does not read in a lower and upper bound for the string describing the tag. The chunk ID is always 4 bytes, and obviously does not have the Ada bounds (dope) information ahead of it in the file. Because a String is an array type, String'Input() which is indirectly called by Chunk_Hdr'Class'Input(), will need to read in array information first. Once the string bounds are known, then the string array is created, and String'Read() is then called to read in the contents of the Tag. I cannot override the String'Input() routine, since I can only do that for a type derived from String (which is of no help here). The only alternative that seems to be present is to override the Chunk_Hdr'Class'Input attribute, and provide my own routine. But this will mean that everytime I add a new derived class (from Chunk_Hdr), that I'll have to go back and revisit and revise this Input procedure. I was hoping to achieve something more elegant. > Probably what you should be doing is calling the stream's > Ada.Streams.Read routine directly from your own custom procedure (*not* > from an attribute). The S'Input() procedure reads the extra dope information about the sizes of arrays (like String), discriminants etc., BEFORE calling the 'Read procedure. You cannot read in a String until it is determined how large it is. Ada reads in a lower and upper bound in the 'Input routine, prior to calling the 'Read routine. I am currently getting a STORAGE_ERROR because it reads in some data for the bounds (which are 2 4 byte integer values, which happens to be the ASCII for the String contents). Once the bad bounds information has been read by the Ada String'Input() routine, it then attempts to allocate a string of that size, to be followed by a String'Read into the array. > Otherwise you'll have to permanentaly specify (in > some cases, changing) how every type you use is read and written to and > from all streams. This is obviously what I am trying to avoid :-) > Streams are really best for: > o hetrogenious data Yep. > o unstructured data (no record boundries) Yep. > o data written *and* read from Ada Eventually.. right now just reading Wave files. > o writer and reader programs use same stream source files Nope, if I understand this correctly. > o data written and read from code using the same compiler The format is dictated by Mickeysoft.. and is fixed. > o data written and read from code using the same platform Platform issues have been solved. I already have a Au_Streams package for reading *.au sound files (*.au files have a simple header, followed by sample data). My Au_Streams package derives from the Audio_Streams package, which is derived from the Endian_Streams package, derived from the Root_Streams_Type. The Endian_Streams package and its types allow me to remove the endian differences in most CPU architectures without the application even knowing about it. All that is required is a little Endian configuration when the stream is initially opened. This greatly simplifies the rest of the application. Wave files however, are more complex, due to the number of different records and the flexibility of their placement. > The less of these bullets you can check off, the more trouble you are > going to have. If you can't check off at least two, you are in big trouble. Working with Microsoft Wave files is trouble enough. I already did one implementation of the partial app the hard way. This time around I am trying to use a stream derived from Audio_Streams as input to the CODEC, and another stream derived from Audio_Streams as the output for the CODEC. I have this concept working for *.au files and a DSP_Streams stream for writing samples to /dev/dsp. Addressing Wave files in this fashion however, is rather messy. I simply am looking at ways to eliminate much extra code, hence human error ;-) I hope above additional description helps. -- Warren W. Gay VE3WWG http://members.home.net/ve3wwg