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,2e66fe8b30e3ee2c X-Google-Attributes: gid103376,public From: Marin David Condic Subject: Re: S'Write and How To Count Bytes Date: 2000/10/02 Message-ID: <39D892AF.BB5F0C54@acm.org>#1/1 X-Deja-AN: 676626712 Content-Transfer-Encoding: 7bit References: <39D6891A.7DC448B6@acm.org> X-Accept-Language: en X-Server-Date: 2 Oct 2000 13:50:59 GMT Content-Type: text/plain; charset=us-ascii Organization: Quadrus Corporation Mime-Version: 1.0 Newsgroups: comp.lang.ada Date: 2000-10-02T13:50:59+00:00 List-Id: tmoran@bix.com wrote: > > Is there any good way of determining in advance how many bytes you are > > going to get when converting an object to a stream? > I don't think I understand. Why not > type Buffer_Type is new Root_Stream_Type with record > Last : Natural := 0; > Data : Stream_Element_Array(1 .. 1000); > end record; > Then each 'write can append its stuff to Data and increment Last > and when they have all finished you have a count and a Stream_Element_Array > to pass to your IO output routine. > ----------------- Well, that's pretty much what I said was one possible solution. Convert it to a stream, counting the bytes as you go. But suppose your record type looks a little more like this: type Some_Rec is tagged record Number_Of_Bytes_To_Pick_Up_Off_The_Wire : Natural ; Some_Piece_Of_Data : Any_Type_You_Like ; end record ; In the application at hand, I've got a listener at the other end of the wire expecting to see a count of how many bytes to pick up before processing. Before sending down the wire, I've got to fill in that number. I'd also like to do it in such a way that I can manage it for Some_Rec'Class so that by dispatching, all the other types derived from it are correctly handled. Now with your Buffer_Type I could do Some_Rec'Class'Write (Buff_Ptr, My_Rec); Then, (if you were a really swell guy and gave me all the right calls) I could go: My_Rec.Number_Of_Bytes_To_Pick_Up_Off_The_Wire := Toms_Pack.Bytes_In_Buffer ; Toms_Pack.Discard_Buffer (Buffer_Object) ; Some_Rec'Class'Write (Buff_Ptr, My_Rec) ; Toms_Pack.Go_Ahead_And_Send_It_Now (Buffer_Object) ; Did I explain that better this time? Hope so. You see the double-conversion of the record to a stream. That's got to be inefficient. If there were some way of knowing in advance how many bytes the record was going to take up in the stream, we could save that double-conversion. I'd like to be able to do this with some version of My_Rec'Size but I've been up and down this direction a thousand times and can never arrive at a satisfactory answer. You've got to be able to control representation, alignment of type extensions and remove the tag in the process of converting to a stream. You can't really use the 'Write in that case because you're counting on your representation to handle how it looks in the stream. (You might get there by accident, but when you're building a communication link to the outside world, you've *really* got to be sure it gets into that stream *exactly* the way you said it would or you're going to have some really upset people at the other end of the wire. Compiler changes could really mess you up there.) If you can't get there with representation clauses, you could conceivably get there with 'Write and making sure you control the sizes of the elementary types. I think I've got enough guarantees from the ARM with respect to elementary types that if I stick to things like UInt_16 and SInt_32 and other things that never pack down below the size of a byte, that the 'Write attribute will give you all this stuff packed end-to-end, pretty much like you'd anticipate. Hence your message representation is controlled by the 'Write. This is, of course, inherently slow in comparison to using a representation clause controlled record and a byte array overlay, but for this app, I'm not on a tiny little processor with no memory and 90% CPU utilization and I've got maybe 500mSec to get the job done. So I can eat the overhead of a bazillion tiny little subprogram calls to get the data in the stream. But I'd sure hate to have to eat that overhead *twice*! Thanks for the input. MDC -- ====================================================================== Marin David Condic - Quadrus Corporation - http://www.quadruscorp.com/ Send Replies To: m c o n d i c @ q u a d r u s c o r p . c o m Visit my web site at: http://www.mcondic.com/ "Giving money and power to Government is like giving whiskey and car keys to teenage boys." -- P. J. O'Rourke ======================================================================