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-Thread: 103376,60c0f30dbde782f6 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit X-Received: by 10.180.74.74 with SMTP id r10mr2225200wiv.3.1357843679874; Thu, 10 Jan 2013 10:47:59 -0800 (PST) Path: i11ni355617wiw.0!nntp.google.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: Record Elements and Endian Conversion Date: Thu, 10 Jan 2013 20:47:57 +0200 Organization: Tidorum Ltd Message-ID: References: Mime-Version: 1.0 X-Trace: individual.net T0M5vReErDvBk2Gcg1DDzQo5EmJ8JHOYl7FsB7VDX+NjePjkzooax4Ns8Kr180UCrT Cancel-Lock: sha1:65JfOxncOOp4y8QMtdq/92eB9lg= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:17.0) Gecko/20130107 Thunderbird/17.0.2 In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Date: 2013-01-10T20:47:57+02:00 List-Id: On 13-01-10 19:31 , awdorrin wrote: > I am migrating legacy code written for the PowerPC platform to X86, > and have been running into Endian issues throughout the code. > > In the latest issue I've discovered, a section of code in which a > record has been defined that has 111 components of various data > types. > > Is there any mechanism within Ada that would provide a way to iterate > across all components of a record, perhaps providing their data > types? One way, sort of, is to use stream I/O. The default (compiler-defined) 'Read, 'Write etc. procedures for the record type traverse the record components in declaration order and call the 'Read or 'Write, etc., procedure for the component type, on the component. If you override the 'Read etc. for the component types, but use the default 'Read for the record type, the result is rather like an iteration over the components that calls your 'Read, etc., and then you can do what you like with the component values. > Problem I have is that this record is used (via a MEMCPY call) to > populate a buffer used to transmit an message via Ethernet. Argh. > While I > have adjusted the record's representation clause to put the data > fields of the record into the correct bit location, those fields > larger than a byte are of the wrong Endianness within the buffer. I would either swap bytes in the components, using for example bindings to the libc functions htonl, htons, or build the buffer using stream output, as above, with the 'Write procedure for the component types written to produce network order. (Since stream 'Write does not depend on the bit-wise representation of the record, you can remove the rep spec for the record type if you use the 'Write method.) I believe some new Gnat versions have a Gnat-specific attribute to set the endianness of record representations -- and not only the bit-numbering order -- which makes the compiler actually swap endianness when a record component is assigned, if the component has the non-native endianness. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .