* First time Ada has let me down @ 2000-10-25 3:50 Shifty 2000-10-25 0:00 ` Larry Kilgallen ` (6 more replies) 0 siblings, 7 replies; 30+ messages in thread From: Shifty @ 2000-10-25 3:50 UTC (permalink / raw) OK, here's the story: I had a problem at work where I needed to calculate the offset of a "magic number" within a buffer containing an IP datagram. The magic number is 3 protocol headers deep within the datagram, and all three headers are variable length. I needed to find the HLEN fields of the IP and TCP headers in memory. Turns out both of these are stored in 4 bits. The data in the other 4 bits of the octet belong to another field in the header. This stumped me for awhile, but then I went home and picked up a C book. Hmmm, chapter 15 - bit fiddling. I learned a bunch of stuff about masks and bitwise operators and came up with a working solution. (which seems much better than using record representation clauses and typecasting a 4 bit value into an 8 bit integer) Next morning I tried to implement the solution and couldn't find the Ada equivalent of C's bit-wise & operater. According to my "Ada as a 2nd language" book, the Ada reserved word "AND" only works for boolean types, not integer types. I got the impression that it was up to the programmer to write his own bitwise ANDs/ORs/XORs, etc (it wouldn't be hard). Luckily I found a vendor-supplied package which provided this functionality, but I can't believe Ada (83) doesn't have native language support for these!!! Please tell me that I am hopelessly confused and dead wrong! Cheers, Andrew. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 3:50 First time Ada has let me down Shifty @ 2000-10-25 0:00 ` Larry Kilgallen 2000-10-25 0:00 ` Ted Dennison 2000-10-25 0:00 ` Ken Garlington ` (5 subsequent siblings) 6 siblings, 1 reply; 30+ messages in thread From: Larry Kilgallen @ 2000-10-25 0:00 UTC (permalink / raw) Ted Dennison <dennison@telepath.com> wrote: > Note to new posters: Always state up front that you are using Ada 83. That seems a bit arbitrary, since he did state Ada 83 in the main question paragraph with which he ended the post. In article <8FD7DEBEEsynoptikdamudderfuck@news>, avlogue@home.com (Shifty) writes: > Luckily I found a vendor-supplied package which provided this > functionality, but I can't believe Ada (83) doesn't have native > language support for these!!! Please tell me that I am hopelessly > confused and dead wrong! Those of us programming in Ada83 measure the quality of implementations by the degree of support provided by such vendor-supplied packages. Yes, standardizing those would be a good idea. The idea that there could be improvements on Ada83 is the reason for Ada95 !!! ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 0:00 ` Larry Kilgallen @ 2000-10-25 0:00 ` Ted Dennison 2000-10-25 0:00 ` Larry Kilgallen 0 siblings, 1 reply; 30+ messages in thread From: Ted Dennison @ 2000-10-25 0:00 UTC (permalink / raw) In article <P3hMgGyKSCbC@eisner.decus.org>, Kilgallen@eisner.decus.org.nospam (Larry Kilgallen) wrote: > Ted Dennison <dennison@telepath.com> wrote: > > > Note to new posters: Always state up front that you are using Ada > > 83. > > That seems a bit arbitrary, since he did state Ada 83 in the main > question paragraph with which he ended the post. At least one poster already has missed that and posted an Ada95 answer. :-( -- T.E.D. http://www.telepath.com/~dennison/Ted/TED.html Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 0:00 ` Ted Dennison @ 2000-10-25 0:00 ` Larry Kilgallen 2000-10-25 0:00 ` Ted Dennison 0 siblings, 1 reply; 30+ messages in thread From: Larry Kilgallen @ 2000-10-25 0:00 UTC (permalink / raw) In article <8t71vg$hsi$1@nnrp1.deja.com>, Ted Dennison <dennison@telepath.com> writes: > In article <P3hMgGyKSCbC@eisner.decus.org>, > Kilgallen@eisner.decus.org.nospam (Larry Kilgallen) wrote: >> Ted Dennison <dennison@telepath.com> wrote: >> >> > Note to new posters: Always state up front that you are using Ada >> > 83. >> >> That seems a bit arbitrary, since he did state Ada 83 in the main >> question paragraph with which he ended the post. > > At least one poster already has missed that and posted an Ada95 answer. > :-( And I have seen posts where the version was indicated other than at the end and people still missed it. There is no magic answer for those who respond before reading, myself included. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 0:00 ` Larry Kilgallen @ 2000-10-25 0:00 ` Ted Dennison 0 siblings, 0 replies; 30+ messages in thread From: Ted Dennison @ 2000-10-25 0:00 UTC (permalink / raw) In article <K79zkIA9hYdm@eisner.decus.org>, Kilgallen@eisner.decus.org.nospam (Larry Kilgallen) wrote: > In article <8t71vg$hsi$1@nnrp1.deja.com>, Ted Dennison <dennison@telepath.com> writes: > > At least one poster already has missed that and posted an Ada95 > > answer. :-( > > And I have seen posts where the version was indicated other than at > the end and people still missed it. There is no magic answer for > those who respond before reading, myself included. True. It was just as likely it was one of my posts too. -- T.E.D. http://www.telepath.com/~dennison/Ted/TED.html Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 3:50 First time Ada has let me down Shifty 2000-10-25 0:00 ` Larry Kilgallen @ 2000-10-25 0:00 ` Ken Garlington 2000-10-25 0:00 ` Shifty 2000-10-25 0:00 ` First time Ada has let me down (recipe) Guillaume ` (4 subsequent siblings) 6 siblings, 1 reply; 30+ messages in thread From: Ken Garlington @ 2000-10-25 0:00 UTC (permalink / raw) "Shifty" <avlogue@home.com> wrote in message news:8FD7DEBEEsynoptikdamudderfuck@news... > OK, here's the story: > > I had a problem at work where I needed to calculate the offset of a > "magic number" within a buffer containing an IP datagram. > > The magic number is 3 protocol headers deep within the datagram, and > all three headers are variable length. I needed to find the HLEN > fields of the IP and TCP headers in memory. Turns out both of these > are stored in 4 bits. The data in the other 4 bits of the octet > belong to another field in the header. > > This stumped me for awhile, but then I went home and picked up a C book. > Hmmm, chapter 15 - bit fiddling. I learned a bunch of stuff about masks > and bitwise operators and came up with a working solution. (which seems > much better than using record representation clauses and typecasting a 4 > bit value into an 8 bit integer) I'm curious about the "typecasting a 4 bit value into an 8 bit integer" statement. Why would you need to do this? 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; > Next morning I tried to implement the solution and couldn't find the Ada > equivalent of C's bit-wise & operater. According to my "Ada as a 2nd > language" book, the Ada reserved word "AND" only works for boolean types, > not integer types. I got the impression that it was up to the programmer > to write his own bitwise ANDs/ORs/XORs, etc (it wouldn't be hard). > > Luckily I found a vendor-supplied package which provided this > functionality, but I can't believe Ada (83) doesn't have native > language support for these!!! Please tell me that I am hopelessly > confused and dead wrong! > > Cheers, > Andrew. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 0:00 ` Ken Garlington @ 2000-10-25 0:00 ` Shifty 2000-10-26 4:00 ` Jeff Carter 2000-10-26 14:36 ` Ted Dennison 0 siblings, 2 replies; 30+ messages in thread From: Shifty @ 2000-10-25 0:00 UTC (permalink / raw) Ken.Garlington@computer.org (Ken Garlington) wrote in <sJAJ5.8835$NP.676523@news.flash.net>: >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. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 0:00 ` Shifty @ 2000-10-26 4:00 ` Jeff Carter 2000-10-26 14:43 ` Ted Dennison ` (2 more replies) 2000-10-26 14:36 ` Ted Dennison 1 sibling, 3 replies; 30+ messages in thread From: Jeff Carter @ 2000-10-26 4:00 UTC (permalink / raw) Shifty wrote: > function Calculate_Ip_Header_Length > (Byte_At : in System.Address) return Integer is It's extremely rare to need to use addresses in all-Ada code except when dealing with hardware, even in Ada 83. It generally indicates either a poor design or a lack of understanding of the capabilities of the language. -- Jeff Carter "You couldn't catch clap in a brothel, silly English K...niggets." Monty Python & the Holy Grail ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-26 4:00 ` Jeff Carter @ 2000-10-26 14:43 ` Ted Dennison 2000-10-26 17:55 ` tmoran 2000-10-26 17:12 ` Shifty 2000-10-26 22:27 ` Guillaume 2 siblings, 1 reply; 30+ messages in thread From: Ted Dennison @ 2000-10-26 14:43 UTC (permalink / raw) In article <39F7AC37.FF6445D@acm.org>, Jeff Carter <jrcarter@acm.org> wrote: > It's extremely rare to need to use addresses in all-Ada code except > when dealing with hardware, even in Ada 83. ... ..or in dealing with imported code and objects, which is what this case is. A binding to some C facility like TCP/IP and sockets is going to be chock full of addresses and/or Unchecked_Conversion's. (The "for use at" overlay makes me wince a bit though). The trick is to not export those ugly address-based interfaces past the bindings. -- T.E.D. http://www.telepath.com/~dennison/Ted/TED.html Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-26 14:43 ` Ted Dennison @ 2000-10-26 17:55 ` tmoran 0 siblings, 0 replies; 30+ messages in thread From: tmoran @ 2000-10-26 17:55 UTC (permalink / raw) >A binding to some C facility like TCP/IP and sockets is going to be >chock full of addresses and/or Unchecked_Conversion's. The 2600 line package body of Claw.Sockets has two instances of address-access conversion, both of the form: P_Aliased_Data := To_Pointer(To_Address(P_Aliased_Data) + Storage_Offset(Result)); It has 10 instantiations of Unchecked_Conversion (localized in specific routines), in two forms: (Interfaces.C.Char, Ada.Streams.Stream_Element); and (Source => Object_Pointer, Target => Claw.Win32.Lpcstr); ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-26 4:00 ` Jeff Carter 2000-10-26 14:43 ` Ted Dennison @ 2000-10-26 17:12 ` Shifty 2000-10-27 1:00 ` Jeff Carter 2000-10-26 22:27 ` Guillaume 2 siblings, 1 reply; 30+ messages in thread From: Shifty @ 2000-10-26 17:12 UTC (permalink / raw) jrcarter@acm.org (Jeff Carter) wrote in <39F7AC37.FF6445D@acm.org>: >Shifty wrote: >> function Calculate_Ip_Header_Length >> (Byte_At : in System.Address) return Integer is > >It's extremely rare to need to use addresses in all-Ada code except when >dealing with hardware, even in Ada 83. It generally indicates either a >poor design or a lack of understanding of the capabilities of the >language. > I couldn't agree more, but in this particular case I'm trying to track down problems in an Ada TCP/IP stack which was literally translated from C. It's the absolute worst Ada code I've seen. I've even run across several goto statements in there. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-26 17:12 ` Shifty @ 2000-10-27 1:00 ` Jeff Carter 0 siblings, 0 replies; 30+ messages in thread From: Jeff Carter @ 2000-10-27 1:00 UTC (permalink / raw) Shifty wrote: > I couldn't agree more, but in this particular case I'm trying to track down > problems in an Ada TCP/IP stack which was literally translated from C. > It's the absolute worst Ada code I've seen. I've even run across several > goto statements in there. I guess it must have been pretty bad C, too. -- Jeff Carter "We burst our pimples at you." Monty Python & the Holy Grail ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-26 4:00 ` Jeff Carter 2000-10-26 14:43 ` Ted Dennison 2000-10-26 17:12 ` Shifty @ 2000-10-26 22:27 ` Guillaume 2000-10-26 21:49 ` Keith Thompson 2 siblings, 1 reply; 30+ messages in thread From: Guillaume @ 2000-10-26 22:27 UTC (permalink / raw) Jeff Carter wrote: > Shifty wrote: > > function Calculate_Ip_Header_Length > > (Byte_At : in System.Address) return Integer is > > It's extremely rare to need to use addresses in all-Ada code except when > dealing with hardware, even in Ada 83. It generally indicates either a > poor design or a lack of understanding of the capabilities of the > language. Agreed ! Aliasing effective parameters is not a good way to employ the "use at" clause, as it may break program execution especially with optimization options turned on. I've experienced this myself, the compiler I use at work produces executables which raise program_error on such code. I've not investingated a lot but with a procedure with a small enough effective parameter, the compiler I use seems to copy this parameter in a CPU register making the "use at" clause totally wrong ! I may seem to repeat here but ... the RM is your friend ... "Address clauses should not be used to achieve overlays of objects or overlays of program units. Nor should a given interrupt be linked to more than one entry. Any program using address clauses to achieve such effects is erroneous." Point your browser to : http://www.adahome.com/LRM/83/RM/rm83html/lrm-13-05.html#13.5 Guillaume ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-26 22:27 ` Guillaume @ 2000-10-26 21:49 ` Keith Thompson 0 siblings, 0 replies; 30+ messages in thread From: Keith Thompson @ 2000-10-26 21:49 UTC (permalink / raw) Guillaume <guifo@wanadoo.fr> writes: [...] > "Address clauses should not be used to achieve overlays of objects or > overlays of program units. Nor should a given interrupt be linked to more > than one entry. Any program using address clauses to achieve such effects > is erroneous." Note that this rule is relaxed somewhat in Ada 95. The new wording (RM95-13.3(13)) is If an Address is specified, it is the programmer's responsibility to ensure that the address is valid; otherwise, program execution is erroneous. -- Keith Thompson (The_Other_Keith) kst@cts.com <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst> Welcome to the last year of the 20th century. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 0:00 ` Shifty 2000-10-26 4:00 ` Jeff Carter @ 2000-10-26 14:36 ` Ted Dennison 2000-10-26 17:55 ` tmoran 1 sibling, 1 reply; 30+ messages in thread From: Ted Dennison @ 2000-10-26 14:36 UTC (permalink / raw) In article <8FD8A9ED5andrewloguecdcgycom@142.77.1.194>, nospam.andrew.logue@cdcgy.com (Shifty) wrote: > 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; If you feel you *have* to do this kind of thing, I'd generally prefer to see Byte_At unchecked_Converion'ed into an object of type "access Octet_Type". I don't ever use "for use at" to alias things, as it obfuscates the code. If a reader sees "Unchecked_Conversion", they have a pretty good idea what's going on. Its a debatable point though. > Version_Mask : constant Integer := 2#00001111#; > > -- Mask it. > -- > Length : Integer := V_Bits.Bit_And (Temp, Version_Mask); > I don't want to start a war over this, since there is _always_ a In that case, it appears you picked an unfortunate subject name. It seems your real problem isn't that "Ada let you down", but that an obsolete version of Ada isn't letting you do things the exact way you'd do them in C (at least not without resorting to compiler extensions) :-) Of course I can name a couple of other situations where Ada 83 really is liable to "let you down". That's why the language was revised. > 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. I'd say you're pretty much on the money. Of course if you don't care about any of the other fields, you could just as easily use a record with only the one field you care about rep'ed, and then you wouldn't have to worry about the masking (and it would probably be clearer to a reader what is going on). If it were me, I don't think I'd do it the way you're doing it. But you can get it to work that way. If everyone did everything the way *I* think it should be done, it'd probably be a pretty surreal world. :-) -- T.E.D. http://www.telepath.com/~dennison/Ted/TED.html Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-26 14:36 ` Ted Dennison @ 2000-10-26 17:55 ` tmoran 2000-10-26 23:08 ` Ted Dennison 0 siblings, 1 reply; 30+ messages in thread From: tmoran @ 2000-10-26 17:55 UTC (permalink / raw) >Byte_At unchecked_Converion'ed into an object of type "access Octet_Type". That's non-portable. System.Address_To_Access_Conversions is specifically intended to do that correctly. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-26 17:55 ` tmoran @ 2000-10-26 23:08 ` Ted Dennison 0 siblings, 0 replies; 30+ messages in thread From: Ted Dennison @ 2000-10-26 23:08 UTC (permalink / raw) tmoran@bix.com wrote: > >Byte_At unchecked_Converion'ed into an object of type "access Octet_Type". > That's non-portable. System.Address_To_Access_Conversions > is specifically intended to do that correctly. Remember; we're talking Ada 83 here. In this context, there is no such thing as System.Address_To_Access_Conversions. Perhaps I should have advised him to put "Ada 83" in the subject. :-) However, it is a good point that you need to verify that this works on your Ada 83 compiler. It worked with every one I've used, but there are some it doesn't work with. -- T.E.D. Home - mailto:dennison@telepath.com Work - mailto:dennison@ssd.fsi.com WWW - http://www.telepath.com/dennison/Ted/TED.html ICQ - 10545591 ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down (recipe) 2000-10-25 3:50 First time Ada has let me down Shifty 2000-10-25 0:00 ` Larry Kilgallen 2000-10-25 0:00 ` Ken Garlington @ 2000-10-25 0:00 ` Guillaume 2000-10-26 2:45 ` Mats Weber 2000-10-25 0:00 ` First time Ada has let me down wv12 ` (3 subsequent siblings) 6 siblings, 1 reply; 30+ messages in thread From: Guillaume @ 2000-10-25 0:00 UTC (permalink / raw) > Next morning I tried to implement the solution and couldn't find the Ada > equivalent of C's bit-wise & operater. According to my "Ada as a 2nd > language" book, the Ada reserved word "AND" only works for boolean types, > not integer types. I got the impression that it was up to the programmer > to write his own bitwise ANDs/ORs/XORs, etc (it wouldn't be hard). The RM is your friend : http://www.adahome.com/LRM/83/RM/rm83html/lrm-04-05.html#4.5.1 The recipe : * unchecked conversion to a packed array of booleans * bitwise operation on the array * unchecked conversion the other way It's not as clean as the solution provided in Ada95 with "mod integers", as for one basic operation you're getting two extra copies (the two unchecked conversions). Hope this helps ! Guillaume ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down (recipe) 2000-10-25 0:00 ` First time Ada has let me down (recipe) Guillaume @ 2000-10-26 2:45 ` Mats Weber 0 siblings, 0 replies; 30+ messages in thread From: Mats Weber @ 2000-10-26 2:45 UTC (permalink / raw) Guillaume wrote: > It's not as clean as the solution provided in Ada95 with "mod integers", as > for one basic operation you're getting two extra copies (the two unchecked > conversions). You will not get extra copies due to unchecked convervsion if you use a good compiler. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 3:50 First time Ada has let me down Shifty ` (2 preceding siblings ...) 2000-10-25 0:00 ` First time Ada has let me down (recipe) Guillaume @ 2000-10-25 0:00 ` wv12 2000-10-25 0:00 ` Gautier ` (3 more replies) 2000-10-25 4:44 ` Julian Morrison ` (2 subsequent siblings) 6 siblings, 4 replies; 30+ messages in thread From: wv12 @ 2000-10-25 0:00 UTC (permalink / raw) In article <8FD7DEBEEsynoptikdamudderfuck@news>, avlogue@home.com (Shifty) wrote: > OK, here's the story: > > I had a problem at work where I needed to calculate the offset of a > "magic number" within a buffer containing an IP datagram. > > The magic number is 3 protocol headers deep within the datagram, and > all three headers are variable length. I needed to find the HLEN > fields of the IP and TCP headers in memory. Turns out both of these > are stored in 4 bits. The data in the other 4 bits of the octet > belong to another field in the header. > the IP header length occupies the 4 LSB. Assuming p pointing to the byte offset, the length is just len = (*p)&0xf; the TCP header length occupies the 4 MSB. the length in this case is then ((*p)&0xf0)>>4; Things just have to be easy in C, don't they. No wonder 99.99% of the IP stacks in the world are in C and not Ada. Sent via Deja.com http://www.deja.com/ Before you buy. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 0:00 ` First time Ada has let me down wv12 @ 2000-10-25 0:00 ` Gautier 2000-10-25 0:00 ` Gisle Sælensminde ` (2 subsequent siblings) 3 siblings, 0 replies; 30+ messages in thread From: Gautier @ 2000-10-25 0:00 UTC (permalink / raw) > the IP header length occupies the 4 LSB. Assuming p pointing to the > byte offset, > the length is just len = (*p)&0xf; > the TCP header length occupies the 4 MSB. the length in this case > is then ((*p)&0xf0)>>4; > Things just have to be easy in C, don't they. No wonder 99.99% of the > IP stacks in the world are in C and not Ada. Do you really think one can't write "x mod 16" or "x / 16" in Ada, Mr wv12 ? In fact things just have to be easy in C, and they don't - see the mess of #includes escaped from the 1960s computing world... ______________________________________________________ Gautier -- http://members.nbci.com/gdemont/gsoft.htm ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 0:00 ` First time Ada has let me down wv12 2000-10-25 0:00 ` Gautier @ 2000-10-25 0:00 ` Gisle Sælensminde 2000-10-25 0:00 ` Joel Seidman 2000-10-26 6:42 ` tmoran 3 siblings, 0 replies; 30+ messages in thread From: Gisle Sælensminde @ 2000-10-25 0:00 UTC (permalink / raw) In article <8t60eo$m0m$1@nnrp1.deja.com>, wv12@my-deja.com wrote: >In article <8FD7DEBEEsynoptikdamudderfuck@news>, > avlogue@home.com (Shifty) wrote: >> OK, here's the story: >> >> I had a problem at work where I needed to calculate the offset of a >> "magic number" within a buffer containing an IP datagram. >> >> The magic number is 3 protocol headers deep within the datagram, and >> all three headers are variable length. I needed to find the HLEN >> fields of the IP and TCP headers in memory. Turns out both of these >> are stored in 4 bits. The data in the other 4 bits of the octet >> belong to another field in the header. >> >the IP header length occupies the 4 LSB. Assuming p pointing to the >byte offset, >the length is just len = (*p)&0xf; Or len = P and 16#0F# in Ada95 >the TCP header length occupies the 4 MSB. the length in this case >is then ((*p)&0xf0)>>4; Or Shift_Left(P and #16#F0#, 4) in Ada 95. Or if P is represented as a packed boolean array, i.e. it's a bit-array, you can index the bits directly: P(5..8) What you writes is simply wrong. Ada95 is IMHO better than C on bit manipulation. There are more examples then those above. -- Gisle S�lensminde ( gisle@ii.uib.no ) With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. (from RFC 1925) ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 0:00 ` First time Ada has let me down wv12 2000-10-25 0:00 ` Gautier 2000-10-25 0:00 ` Gisle Sælensminde @ 2000-10-25 0:00 ` Joel Seidman 2000-10-26 6:42 ` tmoran 3 siblings, 0 replies; 30+ messages in thread From: Joel Seidman @ 2000-10-25 0:00 UTC (permalink / raw) wv12@my-deja.com wrote: [snip] > the length is just len = (*p)&0xf; > the TCP header length occupies the 4 MSB. the length in this case > is then ((*p)&0xf0)>>4; > Things just have to be easy in C, don't they. No wonder 99.99% of the > IP stacks in the world are in C and not Ada. Depends on what "things" you are talking about. If it's programming complex systems, C does not make it easy. Even if the final debugged C code is "shorter" (your idea of "easy"?), what I care about is how long it took to debug it. You can do the equivalent of the above in Ada, too. Promoting the idea that the above is good style is the reason programs are so fragile. (Hint: Consider how much code in a large program you have to change, and how long it takes to find it all, if the 4-bit field is moved from the right to the left, or somewhere in between.) If C doesn't provide a better way to do it (I'm not certain but I don't think so), then give me Ada. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 0:00 ` First time Ada has let me down wv12 ` (2 preceding siblings ...) 2000-10-25 0:00 ` Joel Seidman @ 2000-10-26 6:42 ` tmoran 3 siblings, 0 replies; 30+ messages in thread From: tmoran @ 2000-10-26 6:42 UTC (permalink / raw) >the length is just len = (*p)&0xf; >the TCP header length occupies the 4 MSB. the length in this case >is then ((*p)&0xf0)>>4; >Things just have to be easy in C, don't they. No wonder 99.99% of the If you really insist on avoiding the tools the language supplies, a rep clause in this case, and "len := buffer(i) mod 16; header_len := buffer(i)/16;" is insufficiently easy, then how about len := len_part(buffer(i)); header_len := Header_len_part(buffer(i)); where len_part : constant array(byte) of integer := (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, ... 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); and similarly for header_len_part. This is quick to write, quick to execute, puts the definitions in a single place where they can be changed without finding all the "and 16#0F"s in the program, and they could even become functions if that became necessary. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 3:50 First time Ada has let me down Shifty ` (3 preceding siblings ...) 2000-10-25 0:00 ` First time Ada has let me down wv12 @ 2000-10-25 4:44 ` Julian Morrison 2000-10-25 4:50 ` Ted Dennison 2000-10-26 21:46 ` Tucker Taft 6 siblings, 0 replies; 30+ messages in thread From: Julian Morrison @ 2000-10-25 4:44 UTC (permalink / raw) Shifty wrote: > [can't flip bits] This is from Ada 95, so I dunno if it will work in 83. Anyway, some thoughts. First, bitwise stuff works with modular numbers, you may be able to just cast it across. Failing that, Ada.Unchecked_Conversion is your friend - convert it to a packed array of boolean, and slice out the bits you need. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 3:50 First time Ada has let me down Shifty ` (4 preceding siblings ...) 2000-10-25 4:44 ` Julian Morrison @ 2000-10-25 4:50 ` Ted Dennison 2000-10-24 0:00 ` Keith Thompson 2000-10-26 0:00 ` Andreas Schulz 2000-10-26 21:46 ` Tucker Taft 6 siblings, 2 replies; 30+ messages in thread From: Ted Dennison @ 2000-10-25 4:50 UTC (permalink / raw) Note to new posters: Always state up front that you are using Ada 83. Its an obsolete standard, so most folks here will assume you are using Ada 95 unless you say otherwise. Shifty wrote: > This stumped me for awhile, but then I went home and picked up a C book. > Hmmm, chapter 15 - bit fiddling. I learned a bunch of stuff about masks > and bitwise operators and came up with a working solution. (which seems > much better than using record representation clauses and typecasting a 4 > bit value into an 8 bit integer) "typecasting"? No such thing in Ada. Integer types are convertable to each other, but that's a simple operation that generates *no* code (except sometimes a range check, which you can disable if you need to). A record rep clause does seem a good way to go, but there are probably others. > Next morning I tried to implement the solution and couldn't find the Ada > equivalent of C's bit-wise & operater. According to my "Ada as a 2nd > language" book, the Ada reserved word "AND" only works for boolean types, > not integer types. I got the impression that it was up to the programmer > to write his own bitwise ANDs/ORs/XORs, etc (it wouldn't be hard). It also works for modular integer types (Ada95 only) and *arrays* of booleans (which can be packed). Either one will do what you want. But if you also want to work with the data as integers, its silly to do it this way, then have to Unchecked_Convert all over the place. Let the record rep clause do the work for you! -- T.E.D. Home - mailto:dennison@telepath.com Work - mailto:dennison@ssd.fsi.com WWW - http://www.telepath.com/dennison/Ted/TED.html ICQ - 10545591 ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 4:50 ` Ted Dennison @ 2000-10-24 0:00 ` Keith Thompson 2000-10-26 0:00 ` Andreas Schulz 1 sibling, 0 replies; 30+ messages in thread From: Keith Thompson @ 2000-10-24 0:00 UTC (permalink / raw) Ted Dennison <dennison@telepath.com> writes: [...] > "typecasting"? No such thing in Ada. Integer types are convertable to each > other, but that's a simple operation that generates *no* code (except > sometimes a range check, which you can disable if you need to). A record rep > clause does seem a good way to go, but there are probably others. A conversion from a smaller to a larger signed integer type is likely to require code to do the sign extension; likewise zero extension for modular types. Also, any conversion with differing sizes may require code to copy the bits from one object to another, though this might be optimized out depending on how the result is used. (OTOH, the copying is often considered part of an assignment, not part of the conversion itself.) -- Keith Thompson (The_Other_Keith) kst@cts.com <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst> Welcome to the last year of the 20th century. ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 4:50 ` Ted Dennison 2000-10-24 0:00 ` Keith Thompson @ 2000-10-26 0:00 ` Andreas Schulz 2000-10-26 18:05 ` Alejandro Villanueva 1 sibling, 1 reply; 30+ messages in thread From: Andreas Schulz @ 2000-10-26 0:00 UTC (permalink / raw) Ted Dennison wrote: > It also works for modular integer types (Ada95 only) and *arrays* of booleans > (which can be packed). Either one will do what you want. But if you also want > to work with the data as integers, its silly to do it this way, then have to > Unchecked_Convert all over the place. Let the record rep clause do the work > for you! I recently tried something similar to eveluate a slightly more complex binary data structure, which ended up as a bunch of nested variant records with representation clauses, using almost all possible sizes from 1..32 bits. Compiling with GNAT, that resulted in several errors like : 'fields of "XXX" must start at storage unit boundary' Apparently, GNAT doesn't like unaligned variant records, or is there any way around that limitation (besides using '/'/mod/and, which is how this stuff is handled now) ? A. Schulz ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-26 0:00 ` Andreas Schulz @ 2000-10-26 18:05 ` Alejandro Villanueva 0 siblings, 0 replies; 30+ messages in thread From: Alejandro Villanueva @ 2000-10-26 18:05 UTC (permalink / raw) Andreas Schulz wrote: > Ted Dennison wrote: > > It also works for modular integer types (Ada95 only) and *arrays* of booleans > > (which can be packed). Either one will do what you want. But if you also want > > to work with the data as integers, its silly to do it this way, then have to > > Unchecked_Convert all over the place. Let the record rep clause do the work > > for you! > > I recently tried something similar to eveluate a slightly more > complex binary data structure, which ended up as a bunch of > nested variant records with representation clauses, using almost > all possible sizes from 1..32 bits. Compiling with GNAT, > that resulted in several errors like : > 'fields of "XXX" must start at storage unit boundary' > Apparently, GNAT doesn't like unaligned variant records, or is there > any way around that limitation (besides using '/'/mod/and, which > is how this stuff is handled now) ? The 'mod is of no use anymore. Ada95 uses 'Alignment. > > > A. Schulz -- ------------------------------------------------------ �Quieres Cobrar por Navegar en Internet? Visita: http://www.navegana.com/dinero/flintstone.html ------------------------------------------------------ Alejandro Villanueva 190921@cepsz.unizar.es ------------------------------------------------------ ^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: First time Ada has let me down 2000-10-25 3:50 First time Ada has let me down Shifty ` (5 preceding siblings ...) 2000-10-25 4:50 ` Ted Dennison @ 2000-10-26 21:46 ` Tucker Taft 6 siblings, 0 replies; 30+ messages in thread From: Tucker Taft @ 2000-10-26 21:46 UTC (permalink / raw) You have received a bunch of answers, not all relevant to Ada 83. It is true that Ada 83 doesn't have support for bit-wise "and"/"or" on integers. However, it has several other features that make that unnecessary. Defining a record type with fields of a 4-bit type (such as "type Bit4 is range 0..15;") and then putting a record representation clause on it would seem to be a good starting point. If you really want to manipulate bits, a packed array of boolean does have "and" and "or", and gives you complete access to individual bits. Finally, you could define a packed array of the 4-bit type (such as the one defined above), and use that to get at individual "nibbles". Unchecked conversion may be necessary somewhere along the way, unless you can use an appropriate rep-spec'ed record or a packed array to represent the entire packet. Although a packed boolean array most directly matches the (limited ;-) capabilities of C, the other mechanisms (such as rep-speced records, or packed array of 4-bit elements) are probably a better fit for the problem. Shifty wrote: > > OK, here's the story: > > I had a problem at work where I needed to calculate the offset of a > "magic number" within a buffer containing an IP datagram. > > The magic number is 3 protocol headers deep within the datagram, and > all three headers are variable length. I needed to find the HLEN > fields of the IP and TCP headers in memory. Turns out both of these > are stored in 4 bits. The data in the other 4 bits of the octet > belong to another field in the header. > ... I can't believe Ada (83) doesn't have native > language support for these!!! Please tell me that I am hopelessly > confused and dead wrong! > > Cheers, > Andrew. -- -Tucker Taft stt@averstar.com http://www.averstar.com/~stt/ Technical Director, Commercial Division, AverStar (formerly Intermetrics) (http://www.averstar.com/services/IT_consulting.html) Burlington, MA USA ^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2000-10-27 1:00 UTC | newest] Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2000-10-25 3:50 First time Ada has let me down Shifty 2000-10-25 0:00 ` Larry Kilgallen 2000-10-25 0:00 ` Ted Dennison 2000-10-25 0:00 ` Larry Kilgallen 2000-10-25 0:00 ` Ted Dennison 2000-10-25 0:00 ` Ken Garlington 2000-10-25 0:00 ` Shifty 2000-10-26 4:00 ` Jeff Carter 2000-10-26 14:43 ` Ted Dennison 2000-10-26 17:55 ` tmoran 2000-10-26 17:12 ` Shifty 2000-10-27 1:00 ` Jeff Carter 2000-10-26 22:27 ` Guillaume 2000-10-26 21:49 ` Keith Thompson 2000-10-26 14:36 ` Ted Dennison 2000-10-26 17:55 ` tmoran 2000-10-26 23:08 ` Ted Dennison 2000-10-25 0:00 ` First time Ada has let me down (recipe) Guillaume 2000-10-26 2:45 ` Mats Weber 2000-10-25 0:00 ` First time Ada has let me down wv12 2000-10-25 0:00 ` Gautier 2000-10-25 0:00 ` Gisle Sælensminde 2000-10-25 0:00 ` Joel Seidman 2000-10-26 6:42 ` tmoran 2000-10-25 4:44 ` Julian Morrison 2000-10-25 4:50 ` Ted Dennison 2000-10-24 0:00 ` Keith Thompson 2000-10-26 0:00 ` Andreas Schulz 2000-10-26 18:05 ` Alejandro Villanueva 2000-10-26 21:46 ` Tucker Taft
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox