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/11 Message-ID: <39E4E762.22DB393D@acm.org>#1/1 X-Deja-AN: 680338037 Content-Transfer-Encoding: 7bit References: <39D8EF78.27E5649F@acm.org> <8s2bf1$j1v4d$1@ID-25716.news.cis.dfn.de> X-Accept-Language: en X-Server-Date: 11 Oct 2000 22:20:53 GMT Content-Type: text/plain; charset=us-ascii Organization: Quadrus Corporation Mime-Version: 1.0 Newsgroups: comp.lang.ada Date: 2000-10-11T22:20:53+00:00 List-Id: I'd agree that Streams are not really the best way to accommodate this because of representation issues. However, I've had representation problems with tagged records when trying to use byte overlays on them instead of streams. I don't think your approach addresses quite what I'd like to do. I want a way of treating the message catalog I've got as if it was a class of related things with certain kinds of common characteristics. I don't think what you're proposing below allows me to do that. It looks like you'd just be overlaying your version of a byte stream on top of some record definitions and calling that the message system. I could have done that with the standard Stream_Element_Array and a bunch of plain-vanilla records. However, what I want is the *elegant*abstraction* of the problem instead of the bit-twiddler answer that I've always seen resorted to with Ada because of fighting rigorous type checking or representation problems. If I have to abandon tagged records, I lose all the nice features of dispatching and class-wide operations. Its not that you can't build something that will work - you just can't do it with grace and pinache. The tagged record and OOP is at least intellectually speaking the "right" approach because a message catalog is a kind of "class" with common operations and common data - but with divergent extensions. The collision seems to occur in that unlike most OO Classes, I've got to a) absolutely control the representation internally and outside of the box and b) I've got to get around strict type checking to be able to alternately treat the messages as either a structured, well-defined record or simply a string of bytes of known length. This is one problem wherein Ada does not seem to give me the ability to get what I want out of it and have to resort to some form of compromise. MDC Nick Roberts wrote: > I would honestly suggest you abandon the use of Ada's streams totally > (except, at least, within the internals of a small package), and define your > own package which formalises the entire message protocol. E.g. (inventing > fictitious commands etc.): > > package SCSI is > > type Device_Type is tagged limited private; > > type Device_Status is (Ready, Busy, Spun_Down, Down); > > function Status (Device: in Device_Type) return Device_Status; > > procedure Reset (Device: in out Device_Type); > > ... > > type Block_List is array (Positive range <>) of Block_Number; > > procedure Get_Bad_Sector_Map ( > Device: in out Device_Type; > Map: out Block_List; > Last: out Natural); > > ... > > Operation_Not_Supported: exception; > > private > > ... > > end SCSI; > > package body SCSI is > > ... > > type Byte_List is array (Positive range <>) of Unsigned_8; > > procedure Send_Bytes (Device: in out Device_Type; Bytes: in Byte_Array) > is > begin > ... > end; > > procedure Read_Bytes (Device: in out Device_Type; Bytes: out Byte_Array) > is > begin > ... > end; > > ... > > procedure Get_Bad_Sector_Map ( > Device: in out Device_Type; > Map: out Block_List; > Last: out Natural) is > > Prelude: Byte_Array(1..1); > Data: Byte_Array(1..4); > > begin > Send_Bytes(Device,(1=>16#0A#)); -- fictitious code for 'GETBSMAP' > Read_Bytes(Device,Prelude); > -- TBD: check Prelude(1) byte > Last := Map'First-1; > loop > Read_Bytes(Device,Data); > if Data = (0,0,0,0) then return; end if; > Last := Last+1; > Map(Last) := ( > Head_Number(Data(1)), > Cylinder_Number(Integer(Data(2))*256+Integer(Data(3))), > Sector_Number(Data(4))); > end loop; > end Get_Bad_Sector_Map; > > ... > > end SCSI; > > You can then allocate memory at exactly the points that make the best sense. > The message protocol itself will determine how efficiently this can be done. > Note how I've illustrated a solution to the unknown length problem similar > to that adopted by Ada.Text_IO.Get_Line on a String. Also note how > SCSI.Device_Type operations can be overridden and extended, neatly > accommodating irregular devices. (Not quite so butt-ugly? ;-) > > -- > Nick Roberts > http://www.AdaOS.org -- ====================================================================== 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 ======================================================================