comp.lang.ada
 help / color / mirror / Atom feed
* Does Ada support endiannes?
@ 2011-12-12  8:57 Gerd
  2011-12-12  9:23 ` Niklas Holsti
  2011-12-12 11:27 ` Dmitry A. Kazakov
  0 siblings, 2 replies; 30+ messages in thread
From: Gerd @ 2011-12-12  8:57 UTC (permalink / raw)


Hello,

a while ago, I worked at Siemens company, with a (CHILL-)compiler that
supports endianess similar to this:

litte : Integer; pragma Datalayout(Little_Endian);
big  : Integer; pragma Dtalayout(Big_Endian);

little := big; -- compiler generates code for converting big endian to
little endian

if little = big -- compiler converts the variables to machines nativ
format before testing


Is there something similar available with Ada? Or has someone any
suggestions how to rewrite it in ada?

Regards,
Gerd



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12  8:57 Does Ada support endiannes? Gerd
@ 2011-12-12  9:23 ` Niklas Holsti
  2011-12-12 11:27 ` Dmitry A. Kazakov
  1 sibling, 0 replies; 30+ messages in thread
From: Niklas Holsti @ 2011-12-12  9:23 UTC (permalink / raw)


On 11-12-12 10:57 , Gerd wrote:
> Hello,
>
> a while ago, I worked at Siemens company, with a (CHILL-)compiler that
> supports endianess similar to this:
>
> litte : Integer; pragma Datalayout(Little_Endian);
> big  : Integer; pragma Dtalayout(Big_Endian);
>
> little := big; -- compiler generates code for converting big endian to
> little endian
>
> if little = big -- compiler converts the variables to machines nativ
> format before testing
>
>
> Is there something similar available with Ada?

No.

> Or has someone any suggestions how to rewrite it in ada?

Assuming that the native format is big-endian, you could define a new type:

    type Little_Endian_Integer is record ... end record;

and write representation specifications to lay out the components of the 
type in a little-endian way. But you would then have write your own 
implementations of all arithmetic operations on Little_Endian_Integer, 
for example the "+" operator, including forms that mix types, for 
example for Integer + Little_Endian_Integer.

In practice, it would be much easier to write only two conversion 
functions, to convert to and from the non-native endianness, and call 
those functions only at the start and end of a computation to load and 
store the variables that use the non-native endianness.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12  8:57 Does Ada support endiannes? Gerd
  2011-12-12  9:23 ` Niklas Holsti
@ 2011-12-12 11:27 ` Dmitry A. Kazakov
  2011-12-12 12:44   ` Gerd
  2011-12-12 12:46   ` Gerd
  1 sibling, 2 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2011-12-12 11:27 UTC (permalink / raw)


On Mon, 12 Dec 2011 00:57:32 -0800 (PST), Gerd wrote:

> a while ago, I worked at Siemens company, with a (CHILL-)compiler that
> supports endianess similar to this:
> 
> litte : Integer; pragma Datalayout(Little_Endian);
> big  : Integer; pragma Dtalayout(Big_Endian);
> 
> little := big; -- compiler generates code for converting big endian to
> little endian
> 
> if little = big -- compiler converts the variables to machines nativ
> format before testing
> 
> 
> Is there something similar available with Ada? Or has someone any
> suggestions how to rewrite it in ada?

You simply convert all inputs when reading them and keep everything in the
native format.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12 11:27 ` Dmitry A. Kazakov
@ 2011-12-12 12:44   ` Gerd
  2011-12-12 19:23     ` Jeffrey Carter
  2011-12-13 14:19     ` Gautier write-only
  2011-12-12 12:46   ` Gerd
  1 sibling, 2 replies; 30+ messages in thread
From: Gerd @ 2011-12-12 12:44 UTC (permalink / raw)


On 12 Dez., 12:27, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

Any suggestion on how to convert, others that "/" and "mod"?



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12 11:27 ` Dmitry A. Kazakov
  2011-12-12 12:44   ` Gerd
@ 2011-12-12 12:46   ` Gerd
  2011-12-12 13:22     ` Dmitry A. Kazakov
  2011-12-12 13:33     ` Robert A Duff
  1 sibling, 2 replies; 30+ messages in thread
From: Gerd @ 2011-12-12 12:46 UTC (permalink / raw)


On 12 Dez., 12:27, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:

Any suggestion on how to convert, others than using "/" and "mod"?



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12 12:46   ` Gerd
@ 2011-12-12 13:22     ` Dmitry A. Kazakov
  2011-12-12 17:07       ` Charles H. Sampson
  2011-12-12 13:33     ` Robert A Duff
  1 sibling, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2011-12-12 13:22 UTC (permalink / raw)


On Mon, 12 Dec 2011 04:46:22 -0800 (PST), Gerd wrote:

> On 12 Dez., 12:27, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
> 
> Any suggestion on how to convert, others than using "/" and "mod"?

Why not to use them? It would be a bad idea trying to avoid them.

It won't give you much performance, because memory mapping would require
unpacking, alignment, checksum evaluation, stuff which would turn into
extra copying. So why not just:

   type Octet is new Unsigned_8;
   type Word is new Unsigned_16;
   type Octet_Array is array (Positive range <>) of Octet;

   procedure Get_Little_Endian (Data : Octet_Array; Index : in out Integer;
      Value : out Word) is -- No extra copying
   begin
      Value := Word (Data (Index)) + Word (Data (Index + 1)) * 256;
      Index := Index + 2;
   end Get_Little_Endian;

Arithmetic is cheap. Memory access is expensive.

Note also, that a real-life protocol could also have specially encoded
values reserved for indication of status (overflow, underflow etc). So
memory mapping would not work anyway.

P.S. We are developing hard real-time communication applications handling
various quite weird hardware protocols. Believe or not, we are using no
representation clauses at all.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12 12:46   ` Gerd
  2011-12-12 13:22     ` Dmitry A. Kazakov
@ 2011-12-12 13:33     ` Robert A Duff
  1 sibling, 0 replies; 30+ messages in thread
From: Robert A Duff @ 2011-12-12 13:33 UTC (permalink / raw)


Gerd <GerdM.O@t-online.de> writes:

> Any suggestion on how to convert, others than using "/" and "mod"?

GNAT has a package called GNAT.Byte_Swapping in g-bytswa.ads.

- Bob



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12 13:22     ` Dmitry A. Kazakov
@ 2011-12-12 17:07       ` Charles H. Sampson
  2011-12-12 18:33         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Charles H. Sampson @ 2011-12-12 17:07 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:

> On Mon, 12 Dec 2011 04:46:22 -0800 (PST), Gerd wrote:
> 
> > On 12 Dez., 12:27, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> > wrote:
> > 
> > Any suggestion on how to convert, others than using "/" and "mod"?
> 
> Why not to use them? It would be a bad idea trying to avoid them.
> 
> It won't give you much performance, because memory mapping would require
> unpacking, alignment, checksum evaluation, stuff which would turn into
> extra copying. So why not just:
> 
>    type Octet is new Unsigned_8;
>    type Word is new Unsigned_16;
>    type Octet_Array is array (Positive range <>) of Octet;
> 
>    procedure Get_Little_Endian (Data : Octet_Array; Index : in out Integer;
>       Value : out Word) is -- No extra copying
>    begin
>       Value := Word (Data (Index)) + Word (Data (Index + 1)) * 256;
>       Index := Index + 2;
>    end Get_Little_Endian;
> 
> ...

     Don't you think this approach obscures what's going on, Dmitry,
thereby negating one of the design goals of Ada?  Sure, most of us who
have bit-twiddled in the bad old days can figure out what's going on, or
at least convince ourselves that we've figured out what's going on, but
I much prefer the clarity of something like

   type Single_Precision is -- old IBM single-precision
      record
         Negative : Boolean;
         Characteristic : Seven_Bit_Integer;
         Mantissa : Twenty_Four_Bit_Fixed_Point;
      end record;

   A_Variable : Single_Precision;

   ...

   A_Variable := (
      Negative => ...
      Characteristic => ...
      Mantissa => ...);

     LIke you, I've worked on a hard real-time system that had to
interface with hardware having a lot of different protocols and
interfaces.  My experience was that worries about code efficiency were
more apparent than real.

                        Charlie

P. S. Please forgive any errors in the syntax of my example.  I don't
have a compiler available to check them with.

P. P. S. I don't advocate the style of the above assignment statement. I
used the first newline only to retain control of the column alignment.
In a reasonable development system, I'd let the editor handle that for
me.
-- 
[A certain TV newsreader] had a role to play: presenter of the Other
Side of the Argument, to whom fair-minded people were obligated to
pay heed, no matter what nonsense he spouted.
Charlie Pierce, Idiot America



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12 17:07       ` Charles H. Sampson
@ 2011-12-12 18:33         ` Dmitry A. Kazakov
  2011-12-14  5:19           ` Charles H. Sampson
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2011-12-12 18:33 UTC (permalink / raw)


On Mon, 12 Dec 2011 09:07:24 -0800, Charles H. Sampson wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> 
>> On Mon, 12 Dec 2011 04:46:22 -0800 (PST), Gerd wrote:
>> 
>>> On 12 Dez., 12:27, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
>>> wrote:
>>> 
>>> Any suggestion on how to convert, others than using "/" and "mod"?
>> 
>> Why not to use them? It would be a bad idea trying to avoid them.
>> 
>> It won't give you much performance, because memory mapping would require
>> unpacking, alignment, checksum evaluation, stuff which would turn into
>> extra copying. So why not just:
>> 
>>    type Octet is new Unsigned_8;
>>    type Word is new Unsigned_16;
>>    type Octet_Array is array (Positive range <>) of Octet;
>> 
>>    procedure Get_Little_Endian (Data : Octet_Array; Index : in out Integer;
>>       Value : out Word) is -- No extra copying
>>    begin
>>       Value := Word (Data (Index)) + Word (Data (Index + 1)) * 256;
>>       Index := Index + 2;
>>    end Get_Little_Endian;
>> 
>> ...
> 
>      Don't you think this approach obscures what's going on, Dmitry,
> thereby negating one of the design goals of Ada?

No. The Ada's design goal was to allow the programmer to describe the
semantics the data types involved and to program in that terms.
Representation clauses rather defeat that idea than support it. The number
read from the wire must look and feel as a number rather than some messy
record, which cannot be a numeric parameter of a generic, has no 'Image, no
meaningful literals etc...

> Sure, most of us who
> have bit-twiddled in the bad old days can figure out what's going on, or
> at least convince ourselves that we've figured out what's going on, but
> I much prefer the clarity of something like
> 
>    type Single_Precision is -- old IBM single-precision
>       record
>          Negative : Boolean;
>          Characteristic : Seven_Bit_Integer;
>          Mantissa : Twenty_Four_Bit_Fixed_Point;
>       end record;
> 
>    A_Variable : Single_Precision;

And defining all arithmetic on it? Elementary functions including? I don't
remember the IBM layout, but are you sure that you have got the order of
fields right? What about the literals?

No, I would never do it this way. In a comparable case:

   http://www.dmitry-kazakov.de/ada/components.htm#IEEE_754

I read IEEE 754 representations into the native floating point rather than
messing up with representation clauses, even if the machine is natively
IEEE 754. I just don't care.

Granted, defining IEEE 754 as a record (Unchecked_Union?), denormalized
numbers, NaN, +/-Inf, hidden mantissa bit, must be a HUGE fun! 

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12 12:44   ` Gerd
@ 2011-12-12 19:23     ` Jeffrey Carter
  2011-12-13 14:25       ` Gerd
  2011-12-13 14:19     ` Gautier write-only
  1 sibling, 1 reply; 30+ messages in thread
From: Jeffrey Carter @ 2011-12-12 19:23 UTC (permalink / raw)


On 12/12/2011 05:44 AM, Gerd wrote:
>
> Any suggestion on how to convert, others that "/" and "mod"?

Let's presume you're on a little-ending machine. Then you can write something like

type Byte is mod 2 ** 8;
for Byte'Size use 8;

type Native is record
    MSB   : Byte;
    MSB_1 : Byte;
    LSB_1 : Byte;
    LSB   : Byte;
end record;

for Native use record
    MSB   at 3 range 0 .. 7;
    MSB_1 at 2 range 0 .. 7;
    LSB_1 at 1 range 0 .. 7;
    LSB   at 0 range 0 .. 7;
end record;
for Native'Size use 32;

function From_Native is new Ada.Unchecked_Conversion
    (Source => Native, Target => Interfaces.Integer_32);
function To_Native is new Ada.Unchecked_Conversion
    (Source => Interfaces.Integer_32, Target => Native);

type Foreign is new Native;

for Foreign use record
    MSB   at 0 range 0 .. 7;
    MSB_1 at 1 range 0 .. 7;
    LSB_1 at 2 range 0 .. 7;
    LSB   at 3 range 0 .. 7;
end record;
for Foreign'Size use 32;

function From_Foreign is new Ada.Unchecked_Conversion
    (Source => Foreign, Target => Interfaces.Integer_32);
function To_Foreign is new Ada.Unchecked_Conversion
    (Source => Interfaces.Integer_32, Target => Foreign);

Now, if you have something in big-endian format in Value, you can convert it to 
little-ending by

From_Native (Native (To_Foreign (Value) ) )

which you would probably want to encapsulate

function Foreign_To_Native (Value : in Interfaces.Integer_32)
return Interfaces.Integer_32 is
    -- null;
begin -- Foreign_To_Native
    return From_Native (Native (To_Foreign (Value) ) );
end Foreign_To_Native;

You could also read your foreign value byte by byte, putting the bytes into the 
appropriate fields of a Native, then unchecked-convert that to an integer.

-- 
Jeff Carter
"Pray that there's intelligent life somewhere up in
space, 'cause there's bugger all down here on earth."
Monty Python's Meaning of Life
61

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12 12:44   ` Gerd
  2011-12-12 19:23     ` Jeffrey Carter
@ 2011-12-13 14:19     ` Gautier write-only
  2011-12-14 16:16       ` Gerd
  1 sibling, 1 reply; 30+ messages in thread
From: Gautier write-only @ 2011-12-13 14:19 UTC (permalink / raw)


On 12 déc, 13:44, Gerd <Gerd...@t-online.de> wrote:

> Any suggestion on how to convert, others that "/" and "mod"?

If you use "/" and "mod" (or "shift"'s and "and"'s to go faster) and
use endianess only for I/O, you'll have perfectly portable solution on
a wide range of compilers and operating systems.

See this:  http://unzip-ada.sf.net/  for an example.
HTH
_________________________
Gautier's Ada programming
http://gautiersblog.blogspot.com/search/label/Ada
NB: follow the above link for a valid e-mail address



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12 19:23     ` Jeffrey Carter
@ 2011-12-13 14:25       ` Gerd
  0 siblings, 0 replies; 30+ messages in thread
From: Gerd @ 2011-12-13 14:25 UTC (permalink / raw)


On 12 Dez., 20:23, Jeffrey Carter <spam.jrcarter....@spam.not.acm.org>
wrote:

Jeffrey,

this looks like what I was looking for. Thanks.

--
Regards,
Gerd



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-12 18:33         ` Dmitry A. Kazakov
@ 2011-12-14  5:19           ` Charles H. Sampson
  2011-12-14  8:56             ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Charles H. Sampson @ 2011-12-14  5:19 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:

> On Mon, 12 Dec 2011 09:07:24 -0800, Charles H. Sampson wrote:
> 
> > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> > 
> >> On Mon, 12 Dec 2011 04:46:22 -0800 (PST), Gerd wrote:
> >> 
> >>> On 12 Dez., 12:27, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> >>> wrote:
> >>> 
> >>> Any suggestion on how to convert, others than using "/" and "mod"?
> >> 
> >> Why not to use them? It would be a bad idea trying to avoid them.
> >> 
> >> It won't give you much performance, because memory mapping would require
> >> unpacking, alignment, checksum evaluation, stuff which would turn into
> >> extra copying. So why not just:
> >> 
> >>    type Octet is new Unsigned_8;
> >>    type Word is new Unsigned_16;
> >>    type Octet_Array is array (Positive range <>) of Octet;
> >> 
> >>    procedure Get_Little_Endian (Data : Octet_Array; Index : in out Integer;
> >>       Value : out Word) is -- No extra copying
> >>    begin
> >>       Value := Word (Data (Index)) + Word (Data (Index + 1)) * 256;
> >>       Index := Index + 2;
> >>    end Get_Little_Endian;
> >> 
> >> ...
> > 
> >      Don't you think this approach obscures what's going on, Dmitry,
> > thereby negating one of the design goals of Ada?
> 
> No. The Ada's design goal was to allow the programmer to describe the
> semantics the data types involved and to program in that terms.
> Representation clauses rather defeat that idea than support it. The number
> read from the wire must look and feel as a number rather than some messy
> record, which cannot be a numeric parameter of a generic, has no 'Image, no
> meaningful literals etc...

     I think I see the place where we have the greatest disagreement in
concept.  To me, in general, data coming "over a wire" are just a stream
of bits until we have interpreted them and found out what they mean.
(The primary, and maybe the only, exception would be a homogenous data
stream.  No interpretation is required.)  So for me, again in general,
there is no such idea as reading a number from such data.  As a result,
I need all sorts of ways of converting bit streams to various internal
data types.

> > Sure, most of us who
> > have bit-twiddled in the bad old days can figure out what's going on, or
> > at least convince ourselves that we've figured out what's going on, but
> > I much prefer the clarity of something like
> > 
> >    type Single_Precision is -- old IBM single-precision
> >       record
> >          Negative : Boolean;
> >          Characteristic : Seven_Bit_Integer;
> >          Mantissa : Twenty_Four_Bit_Fixed_Point;
> >       end record;
> > 
> >    A_Variable : Single_Precision;
> 
> And defining all arithmetic on it? Elementary functions including? I don't
> remember the IBM layout, but are you sure that you have got the order of
> fields right? What about the literals?

     If the a bit stream is interpreted as a target machine native
number, then I have to use two views into each variable of that numeric
type.  One view looks at it as a native number and the other view would
show its component structure.   All the number's operations and
elementary functions are available by using the native number view.

     These two views are a form of aliasing, which I don't like very
much at all.  This can be minimized through the use of conversion
functions, limiting the aliasing to the body of the functions.  There's
no execution penalty to this approach because the conversion functions
are easily inlined.

     At that requires a bit mor writing than your approach, Dmitry, but
that's o. k. with me.  The design of Ada was permitted to require
"extra" writing for the purpose of clarity of code.  If I'm willing to
write voluminous comments to document the source code, and I am, I don't
begrudge a few keystroke when writing code itself.

     I'm 99.97% sure that I have the IBM single-precision layout
correct, including the order, but it doesn't matter.  In practice I
would always use a representation specification.  I always use rep specs
when I'm defining a type whose bit layout (or encoding, for an
enumeration type) has been specified.  In the case of an enumeration
type I do that even if the specification is the LRM-defined one.  My
coding style is that a rep spec means that the layout or encoding has
been specified somewhere.  If it hasn't been, I'm pretty rigorous about
letting the compiler choose the representation.

> No, I would never do it this way. In a comparable case:
> 
>    http://www.dmitry-kazakov.de/ada/components.htm#IEEE_754
> 
> I read IEEE 754 representations into the native floating point rather than
> messing up with representation clauses, even if the machine is natively
> IEEE 754. I just don't care.
> 
> Granted, defining IEEE 754 as a record (Unchecked_Union?), denormalized
> numbers, NaN, +/-Inf, hidden mantissa bit, must be a HUGE fun! 

     I did it and it wasn't a big deal at all.

                        Charlie
-- 
[A certain TV newsreader] had a role to play: presenter of the Other
Side of the Argument, to whom fair-minded people were obligated to
pay heed, no matter what nonsense he spouted.
Charlie Pierce, Idiot America



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-14  5:19           ` Charles H. Sampson
@ 2011-12-14  8:56             ` Dmitry A. Kazakov
  2011-12-14  9:46               ` Simon Wright
  2011-12-15  9:14               ` Charles H. Sampson
  0 siblings, 2 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2011-12-14  8:56 UTC (permalink / raw)


On Tue, 13 Dec 2011 21:19:07 -0800, Charles H. Sampson wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> 
>> No. The Ada's design goal was to allow the programmer to describe the
>> semantics the data types involved and to program in that terms.
>> Representation clauses rather defeat that idea than support it. The number
>> read from the wire must look and feel as a number rather than some messy
>> record, which cannot be a numeric parameter of a generic, has no 'Image, no
>> meaningful literals etc...
> 
>      I think I see the place where we have the greatest disagreement in
> concept.  To me, in general, data coming "over a wire" are just a stream
> of bits until we have interpreted them and found out what they mean.

Right, I prefer typed approaches over untyped ones. This is BTW why I
prefer Ada over other languages.

Stream of bits is a transport layer, at best, to be hidden under higher
protocol layers, spilling properly typed objects to the clients. No
conversions. One advantage of this approach is that the transport being
properly encapsulated could be easily replaced.

>      At that requires a bit mor writing than your approach, Dmitry, but
> that's o. k. with me.  The design of Ada was permitted to require
> "extra" writing for the purpose of clarity of code.

I think the problem here is not the volume of the code, but an untyped
nature of it.

Note that if the native and remote objects were distinct types (not
subtypes), you would not be able to have them as views of the *same*
object. Thus you would have to convert the remote object to a native one.
But once you had the latter you would not need the former anymore. The next
step is just to get rid of it. Why anybody (a client) should see it at all?
That is my approach.

As a by-product you get a highly portable code as Gautier pointed out in
another response.

IMO, representation clauses are evil and not Ada (TM).

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-14  8:56             ` Dmitry A. Kazakov
@ 2011-12-14  9:46               ` Simon Wright
  2011-12-15  9:14               ` Charles H. Sampson
  1 sibling, 0 replies; 30+ messages in thread
From: Simon Wright @ 2011-12-14  9:46 UTC (permalink / raw)


It seems to me that there's violent agreement going on here. The only
point of disagreement is how to convert the stream of bits into native,
unrepresented, application data.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-13 14:19     ` Gautier write-only
@ 2011-12-14 16:16       ` Gerd
  2011-12-14 18:16         ` Dmitry A. Kazakov
  2011-12-14 20:16         ` Gautier write-only
  0 siblings, 2 replies; 30+ messages in thread
From: Gerd @ 2011-12-14 16:16 UTC (permalink / raw)


On 13 Dez., 15:19, Gautier write-only <gautier_niou...@hotmail.com>
wrote:

Are you sure the "/" and mod would work correct?

Assume, that the Value 16#000000FF# shall be converted to
16#FF000000#.

Native : Integer := 16#000000FF#;

Remote : Integer;

Remote := 16#01000000# * ()Native mod 16#000000FF#); -- overflow!

--
Gerd

PS: The task is to exchange Integer Values between an Motorola 68k and
an Intel x86.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-14 16:16       ` Gerd
@ 2011-12-14 18:16         ` Dmitry A. Kazakov
  2011-12-14 20:16         ` Gautier write-only
  1 sibling, 0 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2011-12-14 18:16 UTC (permalink / raw)


On Wed, 14 Dec 2011 08:16:02 -0800 (PST), Gerd wrote:

> On 13 Dez., 15:19, Gautier write-only <gautier_niou...@hotmail.com>
> wrote:
> 
> Are you sure the "/" and mod would work correct?

Always. Arithmetic is complete in the sense that any possible function can
be implemented using these operations.

> Assume, that the Value 16#000000FF# shall be converted to
> 16#FF000000#
>
> Native : Integer := 16#000000FF#;
> 
> Remote : Integer;
> 
> Remote := 16#01000000# * ()Native mod 16#000000FF#); -- overflow!

Either it is not Integer (e.g. Unsigned_32) or else overflow is not an
error but a legal outcome indicating protocol error, for example. The
decision depends on the application.

Note that if you used a representation clause and/or Unchecked_Conversion,
you would have to use X'Valid attribute in order to check obtained value
for being an integer.

For all cases where arithmetic would raise Constraint_Error, X'Value should
yield false, which is not guaranteed of course. This is another reason why
not to use representation clauses, because some illegal representation
might get misinterpreted as proper values.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-14 16:16       ` Gerd
  2011-12-14 18:16         ` Dmitry A. Kazakov
@ 2011-12-14 20:16         ` Gautier write-only
  2011-12-15 11:27           ` Gerd
  1 sibling, 1 reply; 30+ messages in thread
From: Gautier write-only @ 2011-12-14 20:16 UTC (permalink / raw)


On 14 déc, 17:16, Gerd <Gerd...@t-online.de> wrote:
> Are you sure the "/" and mod would work correct?
>
> Assume, that the Value 16#000000FF# shall be converted to
> 16#FF000000#.
>
> Native : Integer := 16#000000FF#;
>
> Remote : Integer;
>
> Remote := 16#01000000# * ()Native mod 16#000000FF#); -- overflow!
>
> PS: The task is to exchange Integer Values between an Motorola 68k and
> an Intel x86.

Then you will use modular types, and with a definite size.
  Native: Unsigned_32;
  Remote: Unsigned_32;
They never overflow.
But typically (as you can see in Zip-Ada [1]) you won't presume
anything about the native endianness.
The "/" and "mod" (or faster: "Shift_Right" and "and") will do the job
automatically for you.
So your code will work on Intel, PowerPC, 68K - whatever - and
communicate with a remote hardware or media with a specific
endianness.

[1] http://unzip-ada.sf.net/za_html/zip-headers__adb.htm#32_12
_________________________
Gautier's Ada programming
http://gautiersblog.blogspot.com/search/label/Ada
NB: follow the above link for a valid e-mail address



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-14  8:56             ` Dmitry A. Kazakov
  2011-12-14  9:46               ` Simon Wright
@ 2011-12-15  9:14               ` Charles H. Sampson
  2011-12-15  9:46                 ` Dmitry A. Kazakov
  1 sibling, 1 reply; 30+ messages in thread
From: Charles H. Sampson @ 2011-12-15  9:14 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:

> On Tue, 13 Dec 2011 21:19:07 -0800, Charles H. Sampson wrote:
> 
> > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> > 
> >> No. The Ada's design goal was to allow the programmer to describe the
> >> semantics the data types involved and to program in that terms.
> >> Representation clauses rather defeat that idea than support it. The number
> >> read from the wire must look and feel as a number rather than some messy
> >> record, which cannot be a numeric parameter of a generic, has no 'Image, no
> >> meaningful literals etc...
> > 
> >      I think I see the place where we have the greatest disagreement in
> > concept.  To me, in general, data coming "over a wire" are just a stream
> > of bits until we have interpreted them and found out what they mean.
> 
> Right, I prefer typed approaches over untyped ones. This is BTW why I
> prefer Ada over other languages.
> 
> Stream of bits is a transport layer, at best, to be hidden under higher
> protocol layers, spilling properly typed objects to the clients. No
> conversions. One advantage of this approach is that the transport being
> properly encapsulated could be easily replaced.

     Well, yes.  You do definitely want to encapsulate all this stuff.
Even though the ugly stuff is hidden to from the clients, I still want
to make the ugly stuff as pretty and understandable as possible.

> >      At that requires a bit more writing than your approach, Dmitry, but
> > that's o. k. with me.  The design of Ada was permitted to require
> > "extra" writing for the purpose of clarity of code.
> 
> I think the problem here is not the volume of the code, but an untyped
> nature of it.

     My code gets "typed" as soon as possible, as soon as I can
recognize what its type is supposed to be.  The reason I wrote _typed_
in quotes is that a stream of bits, where I start, is typed:

   type Bit is range 0 .. 1;
   for Bit'Size use 1;
   type Bit_Stream is array (Positive range <>) of Bit;
   pragma Pack (Bit_Stream);

> Note that if the native and remote objects were distinct types (not
> subtypes), you would not be able to have them as views of the *same*
> object. Thus you would have to convert the remote object to a native one.
> But once you had the latter you would not need the former anymore. The next
> step is just to get rid of it. Why anybody (a client) should see it at all?
> That is my approach.

     The only time I need two views of an object when I need to access
its components, such as when constructing the object or accessing its
components to, for example, construct some other object from them.  I
absolutely agree that you should get numeric values into a proper native
type as soon as possible.  This conversion between native and non-native
type should be confined to IO time.

     Sometime the time between the IO and the conversion is longer than
you might hope, at least on the input side.  Referring again to the last
system I worked on, we often had to read part of the input to determine
the length of the incoming bit string, then read the rest in, and then
begin the checking to determine exactly what we had.

> As a by-product you get a highly portable code as Gautier pointed out in
> another response.

     I don't understand this claim of highly portable code without using
a rep spec.  A rep spec is necessary to insure proper allocation of a
record's components.  Your earlier questioning of the order of the
components in my definition of the type Single_Precision leads me to
think that you aren't aware that there is no link between the lexical
order of a record type definition and the layout of its components in
memory.  In other words, a compiler is free to "move components around".
They usually do this to achieve an efficient memory layout but they
could do in just on a whim of the compiler writer.

> IMO, representation clauses are evil and not Ada (TM).

     IMO, representation clauses are a blessing that allows me to take
full control of the representation when I need to.  That's one of many
reasons why I prefer Ada to any other language I know, to the point that
I refuse to program in any other language.  (Being past retirement age
has certain benefits.)

     By the way, Dmitry, I hope you understand that by carrying on this
dialog I don't intend to imply that you're a idiot who has no idea what
he's doing.  That's obviously not true.  All I'm trying to do is lead
you to enlightenment by exposing you to my clearly superior ideas.  :-)

                        Charlie
-- 
[A certain TV newsreader] had a role to play: presenter of the Other
Side of the Argument, to whom fair-minded people were obligated to
pay heed, no matter what nonsense he spouted.
Charlie Pierce, Idiot America



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-15  9:14               ` Charles H. Sampson
@ 2011-12-15  9:46                 ` Dmitry A. Kazakov
  2011-12-25 21:42                   ` Charles H. Sampson
  0 siblings, 1 reply; 30+ messages in thread
From: Dmitry A. Kazakov @ 2011-12-15  9:46 UTC (permalink / raw)


On Thu, 15 Dec 2011 01:14:15 -0800, Charles H. Sampson wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> 
>> I think the problem here is not the volume of the code, but an untyped
>> nature of it.
> 
>      My code gets "typed" as soon as possible, as soon as I can
> recognize what its type is supposed to be.  The reason I wrote _typed_
> in quotes is that a stream of bits, where I start, is typed:
> 
>    type Bit is range 0 .. 1;
>    for Bit'Size use 1;
>    type Bit_Stream is array (Positive range <>) of Bit;
>    pragma Pack (Bit_Stream);

In order to make this working with representation clause you have to get
bits out of this stream and store them into a properly aligned array of
Storage_Unit. Doing so, you will have to take into account native storage
unit bit endianness, which may differ from the endiannes of the protocol.
Furthermore, since almost all protocols are octet-oriented rather than
bit-oriented, you will need to decode the protocol's stream of octets into
bits and then recode that into an array of storage units to apply a
representation clause on that.

A rationale for such an exercise is beyond me, but certainly this is not
what anybody could call "simple" or "readable."

>      Sometime the time between the IO and the conversion is longer than
> you might hope, at least on the input side.  Referring again to the last
> system I worked on, we often had to read part of the input to determine
> the length of the incoming bit string, then read the rest in, and then
> begin the checking to determine exactly what we had.

Yes, and this is yet another argument against representation clauses which
tend to convert things as a whole. The problem is that protocols are using
finer grained elements, that data might be corrupted, not ready as a whole
etc. Using representation clauses you will have problems with validating
data after conversion. You must ensure that no invalid bit pattern may
become a valid value after re-interpretation using a representation clause.
When using arithmetic of octets this is done in the course of conversion,
almost automatically. With representation clauses you would likely have to
add some extra checks before storing the data and after the
re-interpretation.

>> As a by-product you get a highly portable code as Gautier pointed out in
>> another response.
> 
>      I don't understand this claim of highly portable code without using
> a rep spec.

The semantics of a representation clause depends on the native machine bit
and storage unit endianness, the size of the storage unit, alignment
constraints. The semantics of arithmetic operations and shifts is fully
machine-independent.

The rule of thumb: representation clauses shall be used exclusively for the
machine hardware. This is the only legitimate case for them.

>   All I'm trying to do is lead
> you to enlightenment by exposing you to my clearly superior ideas.  :-)

(:-))

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-14 20:16         ` Gautier write-only
@ 2011-12-15 11:27           ` Gerd
  2011-12-15 13:01             ` Simon Wright
                               ` (2 more replies)
  0 siblings, 3 replies; 30+ messages in thread
From: Gerd @ 2011-12-15 11:27 UTC (permalink / raw)


On 14 Dez., 21:16, Gautier write-only <gautier_niou...@hotmail.com>
wrote:

The problem space requires integers (signed), so using unsigned is not
the right option.

Could you please explain: What do you think how the data send from 68k
to x86 will be converted from one data layout to the other? Will it
happen "magically" on the wire? I think, conversion must be done
explicit either on one side or on the other side, and this requires
some code.

Currently I use the htonl ntohl functions for it, which (as stated
above) is not a good choice as it limits the allowed values to
unsigned.


> On 14 déc, 17:16, Gerd <Gerd...@t-online.de> wrote:
>
> > Are you sure the "/" and mod would work correct?
>
> > Assume, that the Value 16#000000FF# shall be converted to
> > 16#FF000000#.
>
> > Native : Integer := 16#000000FF#;
>
> > Remote : Integer;
>
> > Remote := 16#01000000# * (Native mod 16#000000FF#); -- overflow!
>
> > PS: The task is to exchange Integer Values between an Motorola 68k and
> > an Intel x86.
>
> Then you will use modular types, and with a definite size.
>   Native: Unsigned_32;
>   Remote: Unsigned_32;
> They never overflow.
> But typically (as you can see in Zip-Ada [1]) you won't presume
> anything about the native endianness.
> The "/" and "mod" (or faster: "Shift_Right" and "and") will do the job
> automatically for you.
> So your code will work on Intel, PowerPC, 68K - whatever - and
> communicate with a remote hardware or media with a specific
> endianness.
>
> [1]http://unzip-ada.sf.net/za_html/zip-headers__adb.htm#32_12
> _________________________
> Gautier's Ada programminghttp://gautiersblog.blogspot.com/search/label/Ada
> NB: follow the above link for a valid e-mail address




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-15 11:27           ` Gerd
@ 2011-12-15 13:01             ` Simon Wright
  2011-12-15 13:37             ` Dmitry A. Kazakov
  2011-12-15 20:12             ` Jeffrey Carter
  2 siblings, 0 replies; 30+ messages in thread
From: Simon Wright @ 2011-12-15 13:01 UTC (permalink / raw)


Gerd <GerdM.O@t-online.de> writes:

> The problem space requires integers (signed), so using unsigned is not
> the right option.
>
> Could you please explain: What do you think how the data send from 68k
> to x86 will be converted from one data layout to the other? Will it
> happen "magically" on the wire? I think, conversion must be done
> explicit either on one side or on the other side, and this requires
> some code.
>
> Currently I use the htonl ntohl functions for it, which (as stated
> above) is not a good choice as it limits the allowed values to
> unsigned.

Some code I wrote -- not quite the same problem -- which handles 8-byte
signed quantities and conversion to/from wire format, and works just
fine on i386, x86_64, powerpc, is

   type SNTP_Timestamp is delta 2.0 ** (-32) range -2.0 ** 31 .. 2.0 ** 31;
   for SNTP_Timestamp'Size use 64;

   subtype Timestamp_Slice is Ada.Streams.Stream_Element_Array (1 .. 8);

   function To_Timestamp_Slice
     (T : SNTP_Timestamp) return Timestamp_Slice is
      function Convert
      is new Ada.Unchecked_Conversion (SNTP_Timestamp,
                                       Timestamp_Slice);
      Tmp : constant Timestamp_Slice := Convert (T);
   begin
      if Big_Endian then
         return Tmp;
      else
         return (1 => Tmp (8),
                 2 => Tmp (7),
                 3 => Tmp (6),
                 4 => Tmp (5),
                 5 => Tmp (4),
                 6 => Tmp (3),
                 7 => Tmp (2),
                 8 => Tmp (1));
      end if;
   end To_Timestamp_Slice;


   function To_SNTP_Timestamp (T : Timestamp_Slice) return SNTP_Timestamp is
      function Convert is new Ada.Unchecked_Conversion (Timestamp_Slice,
                                                        SNTP_Timestamp);
   begin
      if Big_Endian then
         return Convert (T);
      else
         return Convert ((1 => T (8),
                          2 => T (7),
                          3 => T (6),
                          4 => T (5),
                          5 => T (4),
                          6 => T (3),
                          7 => T (2),
                          8 => T (1)));
      end if;
   end To_SNTP_Timestamp;

No real possibility of validation of this data type at the conversion
level, of course.

I think the chance of using wierd machines where this doesn't work is
pretty low.

And don't forget you can come a cropper because of compiler changes:
previous to Ada 2005, GNAT's representation of Ada.Calendar.Time used
the Unix epoch, so a conversion based on that seemed a pretty safe bet.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-15 11:27           ` Gerd
  2011-12-15 13:01             ` Simon Wright
@ 2011-12-15 13:37             ` Dmitry A. Kazakov
  2011-12-15 20:12             ` Jeffrey Carter
  2 siblings, 0 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2011-12-15 13:37 UTC (permalink / raw)


On Thu, 15 Dec 2011 03:27:48 -0800 (PST), Gerd wrote:

> Could you please explain: What do you think how the data send from 68k
> to x86 will be converted from one data layout to the other?

Assuming 68k is big endian, two's complement:

   type Octet is new Unsigned_8;
   function From_Motorola (First, Second : Octet) return Integer_16 is
   begin
      if First > 127 then
         return -1 - Integer_16 (not First) * 256 -
            Integer_16 (not Second);
      else
         return Integer_16 (First) * 256 + Integer_16 (Second);
      end if;
   end From_Motorola;

Note that the code is target machine's endianness agnostic.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-15 11:27           ` Gerd
  2011-12-15 13:01             ` Simon Wright
  2011-12-15 13:37             ` Dmitry A. Kazakov
@ 2011-12-15 20:12             ` Jeffrey Carter
  2 siblings, 0 replies; 30+ messages in thread
From: Jeffrey Carter @ 2011-12-15 20:12 UTC (permalink / raw)


On 12/15/2011 04:27 AM, Gerd wrote:
>
> The problem space requires integers (signed), so using unsigned is not
> the right option.

What you're talking about is not values, but bit patterns. Until you get the bit 
pattern correct, you can't think about the value. In Ada, bit patterns are 
represented by modular integers, packed arrays of Boolean, or records with 
representation clauses. Once you have the bit pattern correct, you use 
Unchecked_Conversion to interpret the bit pattern as a value of the desired type 
(signed integer in this case).

It depends on how you're getting the bytes that hold the bit pattern in question.

If you're getting individual bytes, from the network for example, then you can 
stick those bytes in the appropriate parts of a structure of the right size 
(array of 4 bytes or record containing 4 1-byte components) and 
unchecked-convert that into your target type.

If for some reason you're starting with signed integer values with the bytes 
scrambled, then you need to uncheck-convert that to get at the bit pattern, do 
the byte swapping, and uncheck-convert the result back to the target type. In 
this case, the automatic conversion between derived types with different 
representations I outlined earlier does the byte swapping for you. Of course, 
you can always unchecked-convert to a bit pattern representation and do the byte 
swapping yourself.

-- 
Jeff Carter
"I would never want to belong to any club that
would have someone like me for a member."
Annie Hall
41

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-15  9:46                 ` Dmitry A. Kazakov
@ 2011-12-25 21:42                   ` Charles H. Sampson
  2011-12-26 10:47                     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 30+ messages in thread
From: Charles H. Sampson @ 2011-12-25 21:42 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:

> On Thu, 15 Dec 2011 01:14:15 -0800, Charles H. Sampson wrote:
> 
> > Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> > 
> >> I think the problem here is not the volume of the code, but an untyped
> >> nature of it.
> > 
> >      My code gets "typed" as soon as possible, as soon as I can
> > recognize what its type is supposed to be.  The reason I wrote _typed_
> > in quotes is that a stream of bits, where I start, is typed:
> > 
> >    type Bit is range 0 .. 1;
> >    for Bit'Size use 1;
> >    type Bit_Stream is array (Positive range <>) of Bit;
> >    pragma Pack (Bit_Stream);
> 
> In order to make this working with representation clause you have to get
> bits out of this stream and store them into a properly aligned array of
> Storage_Unit. Doing so, you will have to take into account native storage
> unit bit endianness, which may differ from the endiannes of the protocol.
> Furthermore, since almost all protocols are octet-oriented rather than
> bit-oriented, you will need to decode the protocol's stream of octets into
> bits and then recode that into an array of storage units to apply a
> representation clause on that.

     He's baaaaack!  Sorry to leave such a time gap in this thread but I
had to find time during this busy season to commune with the LRM at bit.

> 
> A rationale for such an exercise is beyond me, but certainly this is not
> what anybody could call "simple" or "readable."
> 
> >      Sometime the time between the IO and the conversion is longer than
> > you might hope, at least on the input side.  Referring again to the last
> > system I worked on, we often had to read part of the input to determine
> > the length of the incoming bit string, then read the rest in, and then
> > begin the checking to determine exactly what we had.
> 
> Yes, and this is yet another argument against representation clauses which
> tend to convert things as a whole. The problem is that protocols are using
> finer grained elements, that data might be corrupted, not ready as a whole
> etc. Using representation clauses you will have problems with validating
> data after conversion. You must ensure that no invalid bit pattern may
> become a valid value after re-interpretation using a representation clause.
> When using arithmetic of octets this is done in the course of conversion,
> almost automatically. With representation clauses you would likely have to
> add some extra checks before storing the data and after the
> re-interpretation.

     I'm not clear on what you mean by "representation clauses ... tend
to convert things as a whole".  Representation clauses don't convert
anything.  They just specify how the bits are laid out in memory.  It
doesn't matter how those bits got there.  In the present case, probably
a low-level routine was called telling it to place the incoming packet
at a certain place in memory.  It's only after the bits are in the
proper place that any conversion takes place.  For example, to change
the endianess of a two-byte word, I might write something like

   Internal_Small_Word := 256 * Incoming.Byte_2 + Byte_1;

It's more than likely that I would use a representation clause for
Internal_Small_Word also and just do two assignments:

   Internal_Small_Word.Byte_1 := Incoming.Byte_2;
   Internal_Small_Word.Byte_2 := Incoming.Byte_1;

It won't surprise you when I say that I think the latter is much clearer
as to intent and meaning than any arithmetic manipulating, including my
former example.

     Data corruption is handled by whatever mechanism is in the data
packets to guard against corruption.  In my experience that was usually
a pretty simple-minded checksum.  Whenever a corrupted packet was
detected, all of its data were thrown away.

    As to checks of incoming data before storing, I usually let Ada do
that for me by properly defining the target data type.  I remember
having to occasionally use 'Valid but I don't remember exactly when.  I
think it had something to do with holey enumerations.

> >> As a by-product you get a highly portable code as Gautier pointed out in
> >> another response.
> > 
> >      I don't understand this claim of highly portable code without using
> > a rep spec.
> 
> The semantics of a representation clause depends on the native machine bit
> and storage unit endianness, the size of the storage unit, alignment
> constraints. The semantics of arithmetic operations and shifts is fully
> machine-independent.

     You've given rep clauses more semantics than the LRM.  They simply
specify how bits are laid out.  I (and the people I lead) avoid storage
unit issues by writing component clauses of the form

   for Component use at 0 range ...

That is, the layout is specified relative to the beginning of the
record.  Comments usually tie this to the document that specified the
data layout.

     I could also get around native machine endianess by specifying the
bit order; for some reason I didn't.

     The down side of this form of component clause is that, without the
comments, it is a little obscure.  I decided to make that tradeoff in
order to get better native machine transportability.

> The rule of thumb: representation clauses shall be used exclusively for the
> machine hardware. This is the only legitimate case for them.

     Isn't that what I've been advocating?  Using representation clauses
when the hardware of one machine doesn't match the hardware of another?
I hope nothing I've written was interpreted as meaning you should
sprinkle rep clauses around like holy water.  I religiously avoid using
them except when absolutely necessary.  (Your meaning of "absolutely
necessary" might differ from mine.)

                        Charlie
-- 
Nobody in this country got rich on his own.  You built a factory--good.
But you moved your goods on roads we all paid for.  You hired workers we
all paid to educate. So keep a big hunk of the money from your factory.
But take a hunk and pay it forward.  Elizabeth Warren (paraphrased)



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-25 21:42                   ` Charles H. Sampson
@ 2011-12-26 10:47                     ` Dmitry A. Kazakov
  2011-12-27 10:38                       ` Georg Bauhaus
  2012-01-04  4:33                       ` Charles H. Sampson
  0 siblings, 2 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2011-12-26 10:47 UTC (permalink / raw)


On Sun, 25 Dec 2011 13:42:45 -0800, Charles H. Sampson wrote:

>      I'm not clear on what you mean by "representation clauses ... tend
> to convert things as a whole".  Representation clauses don't convert
> anything.  They just specify how the bits are laid out in memory.

But you want to use them for conversions. You somehow put raw data there
and then reinterpret that as an integral ADT object, usually an integer.
What about a task object? Consider an agent-based application using some
protocol to transport agents (tasks) over the network. Would you
reconstruct an agent from bits and bytes using a representation clause?
(:-))

> For example, to change
> the endianess of a two-byte word, I might write something like
> 
>    Internal_Small_Word := 256 * Incoming.Byte_2 + Byte_1;
> 
> It's more than likely that I would use a representation clause for
> Internal_Small_Word also and just do two assignments:
> 
>    Internal_Small_Word.Byte_1 := Incoming.Byte_2;
>    Internal_Small_Word.Byte_2 := Incoming.Byte_1;
> 
> It won't surprise you when I say that I think the latter is much clearer
> as to intent and meaning than any arithmetic manipulating, including my
> former example.

No. The first variant follows the mathematical definition of how an integer
of the range 0 .. 2**16 - 1 is encoded as a sequence of octets (integers
range 0 .. 2**8 - 1).

Your code uses obscure assignments to some fields of some record type,
which connection to the mathematical definition of an encoded number is not
clear to the reader, as well as the correctness of the code, because the
order of bytes and gaps between them is specified somewhere else by a
representation clause.

Note also that all examples you and others have so far provided, go no
further swapping bytes and trivial bit fields extraction. This is too
little for real-life applications.

Consider a PT100 WAGO Modbus module. It delivers a WORD (two bytes) in
so-called Siemens format. 12 MSBs encode the value from -200 to 883 degree
Celsius represented as 0400..7FF8. Bigger and lesser values are cropped.
The 4 LSBs bits are the diagnostics bits (curcuit open/close etc). You
could not handle this using a representation clause in one step. You will
have first to swap bytes to build a 16 bit integer and use it to obtain the
temperature masking and shifting. Or, first reorder and extract 12 bits,
extract 4 bits, check, recode 12 bits into value. In both cases
arithmetical operations are unavoidable.

>      Data corruption is handled by whatever mechanism is in the data
> packets to guard against corruption.

As I said, you need something to add, in order to check validity of the
values obtained from the conversion. X'Valid is no help in the examples
like above, when values are saturated and/or additional bits or patterns
are used to indicate validness.

Another example chain codes. E.g. the following encoding of cardinal
numbers:

0 -> 2#0000_000#
1 -> 2#0000_0001#
...
127 -> 2#0111_1111#
128 -> 2#1000_0000# 2#0000_0001#
129 -> 2#1000_0001# 2#0000_0001#
...
4095 -> 2#1111_1111# 2#0111_1111#
4096 -> 2#1000_0000# 2#1000_0000# 2#0000_0001# 
...

[Chain codes are used when the upper bound of the transported number is
unspecified and it is expected that lesser values are more frequent than
bigger ones. UTF-8, is chain code.]

Care to write a representation clause for the above?

>> The rule of thumb: representation clauses shall be used exclusively for the
>> machine hardware. This is the only legitimate case for them.
> 
>      Isn't that what I've been advocating?

In that case we are in agreement that they should not be used for handling
I/O protocols.

The only useful examples of representation clauses I saw were descriptions
of machine registers, e.g. the bits of the processor status word, of the
memory mapping registers etc. IMO, this is the only legitimate use for
them: systems programming, machine-specific, once in 10 years or never.

> Using representation clauses
> when the hardware of one machine doesn't match the hardware of another?

All sorts of I/O: reading data from a hardware port, from a socket, from
dual-ported shared memory etc.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-26 10:47                     ` Dmitry A. Kazakov
@ 2011-12-27 10:38                       ` Georg Bauhaus
  2011-12-27 12:35                         ` Dmitry A. Kazakov
  2012-01-04  4:33                       ` Charles H. Sampson
  1 sibling, 1 reply; 30+ messages in thread
From: Georg Bauhaus @ 2011-12-27 10:38 UTC (permalink / raw)


On 26.12.11 11:47, Dmitry A. Kazakov wrote:

> Your code uses obscure assignments to some fields of some record type,

Or, as one might say, the expression

 256 * Incoming.Byte_2 + Byte_1

is an obscure arithmetical formula involving the magic number 256.
It takes careful study by someone with mathematical training and also
requires knowledge of language fine print and data representation or
else 256 is not meaningful, but obscure!
So, regarding obscurity, the formula would at first show little advantage.
Neither will it be more readable in this sense.


> 4095 -> 2#1111_1111# 2#0111_1111#
> 4096 -> 2#1000_0000# 2#1000_0000# 2#0000_0001# 
> ...
> 
> [Chain codes are used when the upper bound of the transported number is
> unspecified and it is expected that lesser values are more frequent than
> bigger ones. UTF-8, is chain code.]
> 
> Care to write a representation clause for the above?

Arguably, a chain code might not what a regular programmer would see
as something to which a record representation clause will apply as a whole.
What will the concrete data type for the above chain code look like,
as a whole, if it is not a list or array of some sort and if, for example,
a chain code is being used precisely because there is a lot more to link
than can be represented in what physically corresponds to
  range 0 .. 2**System.Word_Size?

It seems there is value in distinguishing an encoding from a representation,
and establish their relationship.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-27 10:38                       ` Georg Bauhaus
@ 2011-12-27 12:35                         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2011-12-27 12:35 UTC (permalink / raw)


On Tue, 27 Dec 2011 11:38:32 +0100, Georg Bauhaus wrote:

> On 26.12.11 11:47, Dmitry A. Kazakov wrote:
> 
>> Your code uses obscure assignments to some fields of some record type,
> 
> Or, as one might say, the expression
> 
>  256 * Incoming.Byte_2 + Byte_1
> 
> is an obscure arithmetical formula involving the magic number 256.

   Data (Index) * 2**8 + Data (Index + 1)

> It takes careful study by someone with mathematical training and also
> requires knowledge of language fine print and data representation or
> else 256 is not meaningful, but obscure!

You need mathematical training in order to understand how numbers are
encoded. Representation clauses require much *additional* understanding on
top of that. Difficulties people keep on having with understanding and
proper usage of the clauses reflect this simple fact.

> So, regarding obscurity, the formula would at first show little advantage.
> Neither will it be more readable in this sense.

It is. This is the way these things are defined in first place. E.g.

   http://en.wikipedia.org/wiki/Two_complement

There is simply no other way. The only thing you can do with a number is to
use numeric operations. Anything else is on top of that. Remember that
binary representation of a number is an encoding, itself defined through
mathematical operations.

>> 4095 -> 2#1111_1111# 2#0111_1111#
>> 4096 -> 2#1000_0000# 2#1000_0000# 2#0000_0001# 
>> ...
>> 
>> [Chain codes are used when the upper bound of the transported number is
>> unspecified and it is expected that lesser values are more frequent than
>> bigger ones. UTF-8, is chain code.]
>> 
>> Care to write a representation clause for the above?
> 
> Arguably, a chain code might not what a regular programmer would see
> as something to which a record representation clause will apply as a whole.

Regular programmer does not bother about encoding anyway. But if someone
have to, my advise is: don't waste your time on understanding
representation clauses. They won't help you. Beyond trivial cases, if you
are not a language lawyer, you will never understand why that mess works or
does not work.

> What will the concrete data type for the above chain code look like,

An integer number

> as a whole, if it is not a list or array of some sort and if, for example,
> a chain code is being used precisely because there is a lot more to link
> than can be represented in what physically corresponds to
>   range 0 .. 2**System.Word_Size?

That was another point against representation clauses: they fall short when
it comes to validity checks. The peers of the protocol like above would
impose certain implementation-specific limits on the number range. Upon
decoding (using arithmetic operations), the program would necessarily get
Constraint_Error when the limit is exceeded, and reroute to Protocol_Error.
It is a very simple and effective method handling protocols in general.

> It seems there is value in distinguishing an encoding from a representation,
> and establish their relationship.

(Ah, you know my weakness of giving definitions. (:-))

OK, here it one:

[Machine] representation is an encoding with the alphabet based on the
values of a machine type.

P.S. A not yet mentioned argument against representation clauses is their
unfriendliness to correctness proof and testing (you would likely need a
full coverage test).

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2011-12-26 10:47                     ` Dmitry A. Kazakov
  2011-12-27 10:38                       ` Georg Bauhaus
@ 2012-01-04  4:33                       ` Charles H. Sampson
  2012-01-04 11:56                         ` Dmitry A. Kazakov
  1 sibling, 1 reply; 30+ messages in thread
From: Charles H. Sampson @ 2012-01-04  4:33 UTC (permalink / raw)


Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:

> On Sun, 25 Dec 2011 13:42:45 -0800, Charles H. Sampson wrote:
> 
> >      I'm not clear on what you mean by "representation clauses ... tend
> > to convert things as a whole".  Representation clauses don't convert
> > anything.  They just specify how the bits are laid out in memory.
> 
> But you want to use them for conversions. You somehow put raw data there
> and then reinterpret that as an integral ADT object, usually an integer.

     I don't reinterpret the raw data,  Based on some knowledge of the
data the representation clause defines its interpretation.  Until we get
to that point, the data are, for me, just a string of bits.  Very seldom
is that interpretation an integer; most often it is a somewhat complex
structure of non-homogenous components, the very definition of a record.

> What about a task object? Consider an agent-based application using some
> protocol to transport agents (tasks) over the network. Would you
> reconstruct an agent from bits and bytes using a representation clause?
> (:-))

     I have no concept of a task object being transported over a
network.  The closest I can come is an indicator (integer or enumeration
type) specifying a task object on the receiving machine to be used.  For
anything else, I'll have to wait until I see one to decide what my
strategy would be.

> > For example, to change
> > the endianess of a two-byte word, I might write something like
> > 
> >    Internal_Small_Word := 256 * Incoming.Byte_2 + Byte_1;
> > 
> > It's more than likely that I would use a representation clause for
> > Internal_Small_Word also and just do two assignments:
> > 
> >    Internal_Small_Word.Byte_1 := Incoming.Byte_2;
> >    Internal_Small_Word.Byte_2 := Incoming.Byte_1;
> > 
> > It won't surprise you when I say that I think the latter is much clearer
> > as to intent and meaning than any arithmetic manipulating, including my
> > former example.
> 
> No. The first variant follows the mathematical definition of how an integer
> of the range 0 .. 2**16 - 1 is encoded as a sequence of octets (integers
> range 0 .. 2**8 - 1).

     And the second variant shows how to rearrange some of the incoming
bits to get the same value in native machine form.

> 
> Your code uses obscure assignments to some fields of some record type,
> which connection to the mathematical definition of an encoded number is not
> clear to the reader, as well as the correctness of the code, because the
> order of bytes and gaps between them is specified somewhere else by a
> representation clause.

     And your code uses obscure multiplications that are really a
disguised form of shifts.  If you're thinking shifts, why not use a
shift function?

     From a mathematical point of view, your multiplication code is
treating two bytes of the incoming code as digits in a base 256
representation.  For a mathematician, that's clear.  It can be confusing
and surprising to a non-mathematician.

> Note also that all examples you and others have so far provided, go no
> further swapping bytes and trivial bit fields extraction. This is too
> little for real-life applications.

     The subject of this thread had to do with endianess.

> Consider a PT100 WAGO Modbus module. It delivers a WORD (two bytes) in
> so-called Siemens format. 12 MSBs encode the value from -200 to 883 degree
> Celsius represented as 0400..7FF8. Bigger and lesser values are cropped.
> The 4 LSBs bits are the diagnostics bits (curcuit open/close etc). You
> could not handle this using a representation clause in one step. You will
> have first to swap bytes to build a 16 bit integer and use it to obtain the
> temperature masking and shifting. Or, first reorder and extract 12 bits,
> extract 4 bits, check, recode 12 bits into value. In both cases
> arithmetical operations are unavoidable.

     I'm pretty sure I could do it to my satisfaction but I've got too
many questions about your description to actually write any code.  For
example, are 200 and 883 in decimal or hex?  What about endianess?
Doesn't the value 7FF8 preclude using the 4 LSBs as diagnostic bits?

     Regarding "You could not handle this using a representation clause
in one step.", I don't know what "this" refers to.  Even if I did, what
is the importance of "one step"?  Am I correct in assuming that "one
step" means "one statement"?  If so, that's unimportant to a reasonably
good optimizing compiler, which can ofter encode sequences of statement
as though they were one complex statement.

> >      Data corruption is handled by whatever mechanism is in the data
> > packets to guard against corruption.
> 
> As I said, you need something to add, in order to check validity of the
> values obtained from the conversion. X'Valid is no help in the examples
> like above, when values are saturated and/or additional bits or patterns
> are used to indicate validness.
> 
> Another example chain codes. E.g. the following encoding of cardinal
> numbers:
> 
> 0 -> 2#0000_000#
> 1 -> 2#0000_0001#
> ...
> 127 -> 2#0111_1111#
> 128 -> 2#1000_0000# 2#0000_0001#
> 129 -> 2#1000_0001# 2#0000_0001#
> ...
> 4095 -> 2#1111_1111# 2#0111_1111#
> 4096 -> 2#1000_0000# 2#1000_0000# 2#0000_0001# 
> ...
> 
> [Chain codes are used when the upper bound of the transported number is
> unspecified and it is expected that lesser values are more frequent than
> bigger ones. UTF-8, is chain code.]
> 
> Care to write a representation clause for the above?

     No, because they are not of a record type.  Give me some
information about how the chains are laid out in memory and I should be
able to come up with some useful type definitions.
 
> >> The rule of thumb: representation clauses shall be used exclusively for the
> >> machine hardware. This is the only legitimate case for them.
> > 
> >      Isn't that what I've been advocating?
> 
> In that case we are in agreement that they should not be used for handling
> I/O protocols.
> 
> The only useful examples of representation clauses I saw were descriptions
> of machine registers, e.g. the bits of the processor status word, of the
> memory mapping registers etc. IMO, this is the only legitimate use for
> them: systems programming, machine-specific, once in 10 years or never.
> 
> > Using representation clauses
> > when the hardware of one machine doesn't match the hardware of another?
> 
> All sorts of I/O: reading data from a hardware port, from a socket, from
> dual-ported shared memory etc.

     I started to say once before that I think I see the primary
difference between us but I never quite got it out.  To me, data being
input "over a wire" are a sequence of bits and I use record types with
representation clauses as soon as I can to specify the meaning of those
bits.  You seem to see those data as a stream of bytes that contain
integers in the range 0 .. 255 and you specify the meaning by doing
arithmetic manipulations.  I also believe in "programming with data" and
it appears that you don't, or at least you don't to the degree that I
do.   Those are pretty fundamental differences between us from the
get-go so it's not suprising that we end up with quite different looking
code to accomplish the same task.

     If my characterization of your approach is correct, then how you do
you handle a stream of bytes when some of them represent characters?  Do
you use 'Val?  What do you do when some of the bytes, when combined
properly, represent a "signed" integer (i.e. a value that could be
negative)?

                        Charlie
-- 
Nobody in this country got rich on his own.  You built a factory--good.
But you moved your goods on roads we all paid for.  You hired workers we
all paid to educate. So keep a big hunk of the money from your factory.
But take a hunk and pay it forward.  Elizabeth Warren (paraphrased)



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: Does Ada support endiannes?
  2012-01-04  4:33                       ` Charles H. Sampson
@ 2012-01-04 11:56                         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 30+ messages in thread
From: Dmitry A. Kazakov @ 2012-01-04 11:56 UTC (permalink / raw)


On Tue, 3 Jan 2012 20:33:30 -0800, Charles H. Sampson wrote:

> Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
> 
>> On Sun, 25 Dec 2011 13:42:45 -0800, Charles H. Sampson wrote:
>> 
>>>      I'm not clear on what you mean by "representation clauses ... tend
>>> to convert things as a whole".  Representation clauses don't convert
>>> anything.  They just specify how the bits are laid out in memory.
>> 
>> But you want to use them for conversions. You somehow put raw data there
>> and then reinterpret that as an integral ADT object, usually an integer.
> 
>      I don't reinterpret the raw data,  Based on some knowledge of the
> data the representation clause defines its interpretation.  Until we get
> to that point, the data are, for me, just a string of bits.  Very seldom
> is that interpretation an integer; most often it is a somewhat complex
> structure of non-homogenous components, the very definition of a record.

String of bits (array) /= record.

>> What about a task object? Consider an agent-based application using some
>> protocol to transport agents (tasks) over the network. Would you
>> reconstruct an agent from bits and bytes using a representation clause?
>> (:-))
> 
>      I have no concept of a task object being transported over a
> network.

That is because you have no concept of an object at all. A task is an
object and an integer is also an object. Neither is a string of bits,
though a string of bits could be used to represent [encode] either.

>>> For example, to change
>>> the endianess of a two-byte word, I might write something like
>>> 
>>>    Internal_Small_Word := 256 * Incoming.Byte_2 + Byte_1;
>>> 
>>> It's more than likely that I would use a representation clause for
>>> Internal_Small_Word also and just do two assignments:
>>> 
>>>    Internal_Small_Word.Byte_1 := Incoming.Byte_2;
>>>    Internal_Small_Word.Byte_2 := Incoming.Byte_1;
>>> 
>>> It won't surprise you when I say that I think the latter is much clearer
>>> as to intent and meaning than any arithmetic manipulating, including my
>>> former example.
>> 
>> No. The first variant follows the mathematical definition of how an integer
>> of the range 0 .. 2**16 - 1 is encoded as a sequence of octets (integers
>> range 0 .. 2**8 - 1).
> 
>      And the second variant shows how to rearrange some of the incoming
> bits to get the same value in native machine form.

Value of what? Same to what? Where and how is it defined?

>> Your code uses obscure assignments to some fields of some record type,
>> which connection to the mathematical definition of an encoded number is not
>> clear to the reader, as well as the correctness of the code, because the
>> order of bytes and gaps between them is specified somewhere else by a
>> representation clause.
> 
>      And your code uses obscure multiplications that are really a
> disguised form of shifts.  If you're thinking shifts, why not use a
> shift function?

On the contrary, shifts are disguised multiplications. See the question
above.

Any encoding of integer values *shall* in its definition use arithmetical
operations to reconstruct the value.

A more general statement is that any encoding of whatever object must in
its definition use the operations defined on the corresponding ADT. That
immediately follows from the definition of ADT in a typed language. You
just have no other means to create an object, again, if the language is
typed.

>      From a mathematical point of view, your multiplication code is
> treating two bytes of the incoming code as digits in a base 256
> representation. For a mathematician, that's clear.  It can be confusing
> and surprising to a non-mathematician.

There is no other view, sorry. Encoding is *defined* as a translation into
an alphabet, which in the case of octets are symbols 0,1,..,255.

>> Note also that all examples you and others have so far provided, go no
>> further swapping bytes and trivial bit fields extraction. This is too
>> little for real-life applications.
> 
>      The subject of this thread had to do with endianess.

So?
 
>> Consider a PT100 WAGO Modbus module. It delivers a WORD (two bytes) in
>> so-called Siemens format. 12 MSBs encode the value from -200 to 883 degree
>> Celsius represented as 0400..7FF8. Bigger and lesser values are cropped.
>> The 4 LSBs bits are the diagnostics bits (curcuit open/close etc). You
>> could not handle this using a representation clause in one step. You will
>> have first to swap bytes to build a 16 bit integer and use it to obtain the
>> temperature masking and shifting. Or, first reorder and extract 12 bits,
>> extract 4 bits, check, recode 12 bits into value. In both cases
>> arithmetical operations are unavoidable.
> 
>      I'm pretty sure I could do it to my satisfaction but I've got too
> many questions about your description to actually write any code.  For
> example, are 200 and 883 in decimal or hex?

Decimal.

> What about endianess?

None, in the sense that different ModBus commands allows you to read
individual bytes and/or words at some ModBus addresses, which meaning
depends in the command mode being used. Furthermore, bytes can be
scattered, i.e. lie on non-consequent ModBus addresses. Welcome to the real
world!

> Doesn't the value 7FF8 preclude using the 4 LSBs as diagnostic bits?

No.

>      Regarding "You could not handle this using a representation clause
> in one step.", I don't know what "this" refers to.  Even if I did, what
> is the importance of "one step"?  Am I correct in assuming that "one
> step" means "one statement"?

If the representation clauses could have handled real-life protocols, then
you would need no other means on order to get values out of read data.
Which would mean that all happens in just one step: you read data into
memory and then take values from the data structure located at the
physically same address. That does not work except for quite elementary
cases.

>>>      Data corruption is handled by whatever mechanism is in the data
>>> packets to guard against corruption.
>> 
>> As I said, you need something to add, in order to check validity of the
>> values obtained from the conversion. X'Valid is no help in the examples
>> like above, when values are saturated and/or additional bits or patterns
>> are used to indicate validness.
>> 
>> Another example chain codes. E.g. the following encoding of cardinal
>> numbers:
>> 
>> 0 -> 2#0000_000#
>> 1 -> 2#0000_0001#
>> ...
>> 127 -> 2#0111_1111#
>> 128 -> 2#1000_0000# 2#0000_0001#
>> 129 -> 2#1000_0001# 2#0000_0001#
>> ...
>> 4095 -> 2#1111_1111# 2#0111_1111#
>> 4096 -> 2#1000_0000# 2#1000_0000# 2#0000_0001# 
>> ...
>> 
>> [Chain codes are used when the upper bound of the transported number is
>> unspecified and it is expected that lesser values are more frequent than
>> bigger ones. UTF-8, is chain code.]
>> 
>> Care to write a representation clause for the above?
> 
>      No, because they are not of a record type.

Why should they be?

> Give me some
> information about how the chains are laid out in memory and I should be
> able to come up with some useful type definitions.

They aren't laid anywhere. It is you way of thinking of it. [Which is
inherently flawed, as I am trying to show you by these examples]

The octets are sent over some octet stream, that is all.

>>> Using representation clauses
>>> when the hardware of one machine doesn't match the hardware of another?
>> 
>> All sorts of I/O: reading data from a hardware port, from a socket, from
>> dual-ported shared memory etc.
> 
>      I started to say once before that I think I see the primary
> difference between us but I never quite got it out.  To me, data being
> input "over a wire" are a sequence of bits and I use record types with
> representation clauses as soon as I can to specify the meaning of those
> bits.  You seem to see those data as a stream of bytes that contain
> integers in the range 0 .. 255 and you specify the meaning by doing
> arithmetic manipulations.

No, you are wrong. The transport protocol (wire) can be of any sort. IFF
that protocol is *serial*

http://en.wikipedia.org/wiki/Serial_communication

THEN, per definition of serial, it is a stream of bits. There exist
zillions of protocols which aren't serial.

All this boils down to the definition of encoding. Remember, encoding is a
translation into certain alphabet:

http://en.wikipedia.org/wiki/Encoding

When the alphabet is {0,1}, you have a serial or binary protocol. There are
other alphabets, you know. Network protocols use streams of octets
{0,1,2,...,255}, or packets of octets. The typewriter uses letters. Morse
Code uses dot and dash, etc.

> I also believe in "programming with data" and
> it appears that you don't, or at least you don't to the degree that I
> do.   Those are pretty fundamental differences between us from the
> get-go so it's not suprising that we end up with quite different looking
> code to accomplish the same task.

Well, if you believe in "programming with data," then there must be
"programming without data" in your world... Not in mine.

>      If my characterization of your approach is correct, then how you do
> you handle a stream of bytes when some of them represent characters?

That depends on:

1. the meaning of the word byte

2. the character type. We have many in Ada.

3. the encoding. There are many so character encodings: UTF-n, USC-n,
EBCDIC, RADIX-50, ASCII, KOI-n, to name a few.

> Do you use 'Val?

If 1 = octet, 2 = Character, 3 = ASCII or Latin-1

> What do you do when some of the bytes, when combined
> properly, represent a "signed" integer (i.e. a value that could be
> negative)?

See 1. You first give the mathematical definition of byte, e.g.

1. Integer range 0..255
2. Integer range -128..127
3. Ordered set of bits {0,1}**8
4. Ordered set of hexadecimal digits {0,1,2,3,5,6,7,8,9,A,B,C,D,E,F}**2
...

based on how the communication hardware and the machine type chosen to
represent byte interact.

Then you define the encoding, i.e. a mapping from the values of the Ada
character type to the symbols the alphabet above. E.g.:

A -> -34
B -> 56
C -> 1
...

Then that mapping gets implemented. If 'Val is appropriate for that, then
why not to use it?

In the real-life octet/Interfaces.Unsigned_8, Character, ASCII covers
almost 90% cases. For them, I am customary using Character'Val.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2012-01-04 11:58 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-12  8:57 Does Ada support endiannes? Gerd
2011-12-12  9:23 ` Niklas Holsti
2011-12-12 11:27 ` Dmitry A. Kazakov
2011-12-12 12:44   ` Gerd
2011-12-12 19:23     ` Jeffrey Carter
2011-12-13 14:25       ` Gerd
2011-12-13 14:19     ` Gautier write-only
2011-12-14 16:16       ` Gerd
2011-12-14 18:16         ` Dmitry A. Kazakov
2011-12-14 20:16         ` Gautier write-only
2011-12-15 11:27           ` Gerd
2011-12-15 13:01             ` Simon Wright
2011-12-15 13:37             ` Dmitry A. Kazakov
2011-12-15 20:12             ` Jeffrey Carter
2011-12-12 12:46   ` Gerd
2011-12-12 13:22     ` Dmitry A. Kazakov
2011-12-12 17:07       ` Charles H. Sampson
2011-12-12 18:33         ` Dmitry A. Kazakov
2011-12-14  5:19           ` Charles H. Sampson
2011-12-14  8:56             ` Dmitry A. Kazakov
2011-12-14  9:46               ` Simon Wright
2011-12-15  9:14               ` Charles H. Sampson
2011-12-15  9:46                 ` Dmitry A. Kazakov
2011-12-25 21:42                   ` Charles H. Sampson
2011-12-26 10:47                     ` Dmitry A. Kazakov
2011-12-27 10:38                       ` Georg Bauhaus
2011-12-27 12:35                         ` Dmitry A. Kazakov
2012-01-04  4:33                       ` Charles H. Sampson
2012-01-04 11:56                         ` Dmitry A. Kazakov
2011-12-12 13:33     ` Robert A Duff

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox