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,ded6ba3fc5b87b66 X-Google-Attributes: gid103376,public From: nospam.andrew.logue@cdcgy.com (Shifty) Subject: Re: First time Ada has let me down Date: 2000/10/25 Message-ID: <8FD8A9ED5andrewloguecdcgycom@142.77.1.194>#1/1 X-Deja-AN: 685881693 References: <8FD7DEBEEsynoptikdamudderfuck@news> X-Trace: nnrp1.uunet.ca 972515290 209.167.52.146 (Wed, 25 Oct 2000 19:08:10 EDT) Organization: Computing Devices Canada User-Agent: Xnews/2.11.08 NNTP-Posting-Date: Wed, 25 Oct 2000 19:08:10 EDT Newsgroups: comp.lang.ada Date: 2000-10-25T00:00:00+00:00 List-Id: Ken.Garlington@computer.org (Ken Garlington) wrote in : >I'm curious about the "typecasting a 4 bit value into an 8 bit integer" >statement. Why would you need to do this? Apparently I don't, per comments from Ted and others. I just assumed that it wouldn't be considered an integer type since it is smaller than the system.storage_unit size. >I would have thought the record representation clause approach would be much >preferable than a bunch of >#DEFINEs to describe the header layout. Granted, the fact that the headers >are variable length complicates >things a bit, but just looking at an IPv4 header, I would expect something >like the source code below. In fact, >if you use this approach (records with variant), you might be able to avoid >some of the offset calculations altogether. >You certainly don't need to do any low-level bit twiddling (which is why >this wasn't as big of a deal in Ada83 as >you might think...) > >package IPv4 is > >type Byte is range 0 .. 16#FF#; >for Byte'Size use 8; > >type Version_Type is range 4 .. 4; >subtype Header_Length_Type is Integer range 5 .. 15; >subtype Total_Length_Type is Integer range 0 .. 65_535; > >-- more types for the rest of the header > >type Option_Type is array (1 .. 4) of Byte; >pragma Pack (Option_Type); >type Option_Type_Array is array (Integer range <>) of Option_Type; >pragma Pack (Option_Type_Array); > >type Header_Type (IHL : Header_Length_Type) is record > Version : Version_Type := 4; > Type_of_Service : Byte := 0; > Total_Length : Total_Length_Type; > > -- the rest of the mandatory fields > > case IHL is > when 5 => > null; > when 6 .. Header_Length_Type'Last => > Option : Option_Type_Array(6 .. IHL); > end case; >end record; > >-- record rep spec goes here > >end IPv4; Yep, this looks like a good solution, but it just seemed like too much code to simply calculate the IP header length. In the end I came up with something like this: function Calculate_Ip_Header_Length (Byte_At : in System.Address) return Integer is Version_Length_Descriptor : Octet_Type; for Version_Length_Descriptor use at Byte_At; Temp : Integer := Integer (Version_Length_Descriptor); -- 7 6 5 4 3 2 1 0 -- +-+-+-+-+-+-+-+-+ -- | | | | | | | | | -- +-+-+-+-+-+-+-+-+ -- | Ver | Hlen | -- Define a mask to mask out the high-order bits. -- |||| Version_Mask : constant Integer := 2#00001111#; -- Mask it. -- Length : Integer := V_Bits.Bit_And (Temp, Version_Mask); begin -- Calculate_Ip_Header_Length -- The Hlen field gives the datagram hdr len measured in 32-bit words. -- return Length * (32 / System.Storage_Unit); end Calculate_Ip_Header_Length; I don't want to start a war over this, since there is _always_ a better way of doing things, but this solution seems simple and elegant, especially when I don't give hoot about the rest of the header structure. You just pass the start address of the IP datagram to this function and it quickly returns the byte-length of the header. (assuming, of course, that Hlen contains the right value!) Thankfully Ada95 has native language support for bitwise integer operators. Thank you for your comments guys. Andrew.