comp.lang.ada
 help / color / mirror / Atom feed
* Binary and XML serialization of types
@ 2014-01-23 18:53 hanslad
  2014-01-23 19:15 ` adambeneschan
  0 siblings, 1 reply; 34+ messages in thread
From: hanslad @ 2014-01-23 18:53 UTC (permalink / raw)


Hello,
I am an Ada beginner who is working on a private project.
The project is to implement a protocol which either does binary or xml serialization of the different defined records. 
I have tried to separate all the "encoding" details from the type declaration in a sub package like this:

package A.Types is

   type Guid_Array is array(1 .. 8) of Unsigned_8;
   type Guid is  record
      Data1 : Unsigned_32;
      Data2 : Unsigned_16;
      Data3 : Unsigned_16;
      Data4 : Guid_Array;
   end record;

end A.Types;


with with Ada.Streams; use Ada.Streams;
package A.Types.BinaryEncoder is

   procedure Guid_Write(
   Stream : access Ada.Streams.Root_Stream_Type'Class; Item : Guid );
   for Guid'Write use Guid_Write;

end A.Types.Encoders;


I get the following error:

7:8 entity must be declared in this Scope

How can I separate all the encoding and decoding details from the type declaration? I like the idea of splitting this into packages with different functionality. Is this possible at all?
Sorry for posting such a beginners question.

Thanks,

HP
   

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

* Re: Binary and XML serialization of types
  2014-01-23 18:53 Binary and XML serialization of types hanslad
@ 2014-01-23 19:15 ` adambeneschan
  2014-01-23 19:17   ` adambeneschan
  2014-01-23 22:44   ` Simon Wright
  0 siblings, 2 replies; 34+ messages in thread
From: adambeneschan @ 2014-01-23 19:15 UTC (permalink / raw)


On Thursday, January 23, 2014 10:53:23 AM UTC-8, han...@gmail.com wrote:
> Hello,
> 
> I am an Ada beginner who is working on a private project.
> 
> The project is to implement a protocol which either does binary or xml serialization of the different defined records. 
> 
> I have tried to separate all the "encoding" details from the type declaration in a sub package like this:
> 
> 
> 
> package A.Types is
> 
>    type Guid_Array is array(1 .. 8) of Unsigned_8;
>    type Guid is  record
>       Data1 : Unsigned_32;
>       Data2 : Unsigned_16;
>       Data3 : Unsigned_16;
>       Data4 : Guid_Array;
>    end record;
> 
> end A.Types;

I think you simply want to do something like this.  Put the declaration of Guid_Write and the "for" clause in A.Types.  Then, in the body of A.Types:

    with A.Types.BinaryEncoder;
    package body A.Types is

       -- other stuff as needed

       procedure Guid_Write( 
           Stream : access Ada.Streams.Root_Stream_Type'Class; Item : Guid )
               renames A.Types.BinaryEncoder.Guid_Write;
                   -- this is called a "renaming-as-body"

or this, which amounts to the same thing:

    with A.Types.BinaryEncoder;
    package body A.Types is

       -- other stuff as needed

       procedure Guid_Write( 
           Stream : access Ada.Streams.Root_Stream_Type'Class; Item : Guid ) is
       begin
           A.Types.BinaryEncoder.Guid_Write (Stream, Item);
       end Guid_Write;

(Note: I think the "renames" will work, but I haven't tested it.  The second one will definitely work.)

Now you declare and implement Guid_Write in A.Types.BinaryEncoder as you were trying to do.  (You don't actually need to give it the same name.  You can call your "implementation" procedure Guid_Write_Impl, or Any_Other_Name_You_Feel_Like.)

What's going on is that if some client package says "with A.Types" and uses the Guid_Write type, and uses Guid_Write'Write(...) or Guid_Write'Output(...), the client has to know that there's a Write routine that isn't the default.  That's why the "for Guid_Write'Write use ..." has to be in the visible part of A.Types, so that other clients are allowed to know about it.
 
                            -- Adam


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

* Re: Binary and XML serialization of types
  2014-01-23 19:15 ` adambeneschan
@ 2014-01-23 19:17   ` adambeneschan
  2014-01-23 19:58     ` hanslad
  2014-01-23 22:44   ` Simon Wright
  1 sibling, 1 reply; 34+ messages in thread
From: adambeneschan @ 2014-01-23 19:17 UTC (permalink / raw)


On Thursday, January 23, 2014 11:15:56 AM UTC-8, I wrote:

> I think you simply want to do something like this.  Put the declaration of Guid_Write and the "for" clause in A.Types.

I meant in the specification of A.Types.  I left a word out.

                                -- Adam


> Then, in the body of A.Types:
> ........



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

* Re: Binary and XML serialization of types
  2014-01-23 19:17   ` adambeneschan
@ 2014-01-23 19:58     ` hanslad
  2014-01-23 20:03       ` adambeneschan
                         ` (2 more replies)
  0 siblings, 3 replies; 34+ messages in thread
From: hanslad @ 2014-01-23 19:58 UTC (permalink / raw)


Thanks Adam,

Ok,that makes sense. 
One more question: Am I on the right path here, or is there a better way to do binary encoding into streams? I want this to perform as fast as possible.

Thanks,

HP



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

* Re: Binary and XML serialization of types
  2014-01-23 19:58     ` hanslad
@ 2014-01-23 20:03       ` adambeneschan
  2014-01-23 21:00       ` Dmitry A. Kazakov
  2014-01-24  8:44       ` Georg Bauhaus
  2 siblings, 0 replies; 34+ messages in thread
From: adambeneschan @ 2014-01-23 20:03 UTC (permalink / raw)


On Thursday, January 23, 2014 11:58:44 AM UTC-8, han...@gmail.com wrote:
> Thanks Adam,
> 
> Ok,that makes sense. 
> 
> One more question: Am I on the right path here, or is there a better way to do binary encoding into streams? I want this to perform as fast as possible.

I'd guess that you're on an OK path, but that isn't my area of expertise.  Perhaps someone else can give a better answer.

                          -- Adam


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

* Re: Binary and XML serialization of types
  2014-01-23 19:58     ` hanslad
  2014-01-23 20:03       ` adambeneschan
@ 2014-01-23 21:00       ` Dmitry A. Kazakov
  2014-01-24  8:54         ` hanslad
  2014-01-24  8:44       ` Georg Bauhaus
  2 siblings, 1 reply; 34+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-23 21:00 UTC (permalink / raw)


On Thu, 23 Jan 2014 11:58:44 -0800 (PST), hanslad@gmail.com wrote:

> One more question: Am I on the right path here, or is there a better way
> to do binary encoding into streams?

The right way is to ensure it portable. That requires overriding default
implementations. Here you can find some examples of portable encoding of
scalar types:

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

> I want this to perform as fast as possible.

Performance is not a big deal because stream I/O takes much more resources
than any conversions.

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

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

* Re: Binary and XML serialization of types
  2014-01-23 19:15 ` adambeneschan
  2014-01-23 19:17   ` adambeneschan
@ 2014-01-23 22:44   ` Simon Wright
  2014-01-23 23:43     ` adambeneschan
  1 sibling, 1 reply; 34+ messages in thread
From: Simon Wright @ 2014-01-23 22:44 UTC (permalink / raw)


adambeneschan@gmail.com writes:

> What's going on is that if some client package says "with A.Types" and
> uses the Guid_Write type, and uses Guid_Write'Write(...) or
> Guid_Write'Output(...), the client has to know that there's a Write
> routine that isn't the default.  That's why the "for Guid_Write'Write
> use ..." has to be in the visible part of A.Types, so that other
> clients are allowed to know about it.

The type was called Guid.

But, more importantly, are you sure about this? GNAT's
Ada.Containers.Vectors, for example, declares the stream-related stuff
in the private part.


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

* Re: Binary and XML serialization of types
  2014-01-23 22:44   ` Simon Wright
@ 2014-01-23 23:43     ` adambeneschan
  2014-01-24  0:58       ` Randy Brukardt
  2014-01-24  8:29       ` Oliver Kleinke
  0 siblings, 2 replies; 34+ messages in thread
From: adambeneschan @ 2014-01-23 23:43 UTC (permalink / raw)


On Thursday, January 23, 2014 2:44:16 PM UTC-8, Simon Wright wrote:

> > What's going on is that if some client package says "with A.Types" and
> > uses the Guid_Write type, and uses Guid_Write'Write(...) or
> > Guid_Write'Output(...), the client has to know that there's a Write
> > routine that isn't the default.  That's why the "for Guid_Write'Write
> > use ..." has to be in the visible part of A.Types, so that other
> > clients are allowed to know about it.
> 
> The type was called Guid.

> But, more importantly, are you sure about this? GNAT's
> Ada.Containers.Vectors, for example, declares the stream-related stuff
> in the private part.

Sorry, I think I must have had caffeine deficiency syndrome when I wrote that.

You're right.  Here's what I should have said:

What's going on is that "for Guid'Write" specifies a property, or "aspect", of the type Guid, and that needs to be done in the same place where Guid is defined, which in this case is the package specification (although it could be in the private part).  

Anyway, my goal was to help the OP understand intuitively why it wouldn't make sense to have a type declared in one package and then allow a property of that type to be changed in some other package.  I hope I got that across, even if I did so badly.

                                 -- Adam 



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

* Re: Binary and XML serialization of types
  2014-01-23 23:43     ` adambeneschan
@ 2014-01-24  0:58       ` Randy Brukardt
  2014-01-24  8:29       ` Oliver Kleinke
  1 sibling, 0 replies; 34+ messages in thread
From: Randy Brukardt @ 2014-01-24  0:58 UTC (permalink / raw)


<adambeneschan@gmail.com> wrote in message 
news:0301ad03-929d-4c9b-8849-494f7f78c777@googlegroups.com...
> On Thursday, January 23, 2014 2:44:16 PM UTC-8, Simon Wright wrote:
>
>> > What's going on is that if some client package says "with A.Types" and
>> > uses the Guid_Write type, and uses Guid_Write'Write(...) or
>> > Guid_Write'Output(...), the client has to know that there's a Write
>> > routine that isn't the default.  That's why the "for Guid_Write'Write
>> > use ..." has to be in the visible part of A.Types, so that other
>> > clients are allowed to know about it.
>>
>> The type was called Guid.
>
>> But, more importantly, are you sure about this? GNAT's
>> Ada.Containers.Vectors, for example, declares the stream-related stuff
>> in the private part.
>
> Sorry, I think I must have had caffeine deficiency syndrome when I wrote 
> that.
>
> You're right.  Here's what I should have said:
>
> What's going on is that "for Guid'Write" specifies a property, or 
> "aspect", of the type Guid,
> and that needs to be done in the same place where Guid is defined, which 
> in this case is
> the package specification (although it could be in the private part).

To clarify (or confuse?) this more, it does have to be visible if Guid is a 
limited type, because in that case it won't have a usable 'Write unless it 
is explicitly defined. For other types, it can be in the private part.

                                  Randy.





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

* Re: Binary and XML serialization of types
  2014-01-23 23:43     ` adambeneschan
  2014-01-24  0:58       ` Randy Brukardt
@ 2014-01-24  8:29       ` Oliver Kleinke
  2014-01-24 16:22         ` adambeneschan
  1 sibling, 1 reply; 34+ messages in thread
From: Oliver Kleinke @ 2014-01-24  8:29 UTC (permalink / raw)


> What's going on is that "for Guid'Write" specifies a property, or
> "aspect"[...]

The term you were looking for is (operational) attribute.


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

* Re: Binary and XML serialization of types
  2014-01-23 19:58     ` hanslad
  2014-01-23 20:03       ` adambeneschan
  2014-01-23 21:00       ` Dmitry A. Kazakov
@ 2014-01-24  8:44       ` Georg Bauhaus
  2014-01-24 17:13         ` Simon Wright
  2 siblings, 1 reply; 34+ messages in thread
From: Georg Bauhaus @ 2014-01-24  8:44 UTC (permalink / raw)


On 23.01.14 20:58, hanslad@gmail.com wrote:
> Thanks Adam,
>
> Ok,that makes sense.
> One more question: Am I on the right path here, or is there a better way to do binary encoding into streams? I want this to perform as fast as possible.

If speed is paramount and the setup permits the same representation
of data at either end of the line, then using the Read and Write
procedures for Stream_Element_Array is likely to be unbeatable
(Streams.Stream_IO).
This suggests conversion of objects of type Guid into objects of
type Stream_Element_Array with the help of an 'Address clause or
through an instance of Unchecked_Conversion. (And some careful
commenting might be a good idea.)


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

* Re: Binary and XML serialization of types
  2014-01-23 21:00       ` Dmitry A. Kazakov
@ 2014-01-24  8:54         ` hanslad
  2014-01-24 10:01           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 34+ messages in thread
From: hanslad @ 2014-01-24  8:54 UTC (permalink / raw)



> 
> The right way is to ensure it portable. That requires overriding default
> 
> implementations. Here you can find some examples of portable encoding of
> 
> scalar types:
> 
> 
> 
> http://www.dmitry-kazakov.de/ada/components.htm#16.3
> 
> 
> 
> > I want this to perform as fast as possible.
> 
> 
> 
> Performance is not a big deal because stream I/O takes much more resources
> than any conversions.



Thank you all for your answers. 
In short, I want to develop a client/server library to encode (and decode) structures of data(records) and request the data over tcp. 
Is there a faster way to do this than using streams?
Also, the encoding of a structure could be dependent of where the structure is used. Say, the first byte sent over wire tells if the "Identity" field in a record should be decoded as a 2 or 4 byte integer. 
For me it would be locical to separate all the "wire information" from the type information. Today, the binary and xml encoding scheme is defined, and I had hope to be able to separate this in different packages. 
What is the locical way to do this?

Thanks.

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

* Re: Binary and XML serialization of types
  2014-01-24  8:54         ` hanslad
@ 2014-01-24 10:01           ` Dmitry A. Kazakov
  2014-01-24 14:44             ` hanslad
  2014-01-24 17:36             ` Simon Wright
  0 siblings, 2 replies; 34+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-24 10:01 UTC (permalink / raw)


On Fri, 24 Jan 2014 00:54:49 -0800 (PST), hanslad@gmail.com wrote:

> In short, I want to develop a client/server library to encode (and decode)
> structures of data(records) and request the data over tcp. 
> Is there a faster way to do this than using streams?

That depends on what you mean here under using streams:

1. Streams for in-memory format transformations

2. Streams as an interface to TCP/IP sockets, e.g. GNAT socket streams.

In the case 1, the alternatives are representation clauses + type
conversion or plain conversion operations. Whatever difference might be, it
is not sufficient.

In the case 2, you should consider using packets instead of a raw octet
stream. Typically you would form an outgoing packet in the memory, using
whatever means (e.g. by a string-mapped stream) and then send the packet
out as a whole. It is especially important to do if you are going to use
NO_DELAY socket option.

> Also, the encoding of a structure could be dependent of where the
> structure is used. Say, the first byte sent over wire tells if the
> "Identity" field in a record should be decoded as a 2 or 4 byte integer.

Is it a custom protocol you are going to invent? Anyway, the protocols
usually deploy some sort of packet header to describe the request and the
body of. The most efficient way is when the body length can be determined
from the header. You read the body into memory and then parse it, e.g.
using a string-mapped stream.

> For me it would be locical to separate all the "wire information" from the
> type information. Today, the binary and xml encoding scheme is defined,
> and I had hope to be able to separate this in different packages.

That is doable.

> What is the locical way to do this?

Deploying OSI model is one way.

I don't know how far up you want to go with XML in breaking the OSI
hierarchy. XML does not make any sense anyway, but considering making it
human-readable as a purpose, you must break it all way up to the
application level, e.g. by exposing names of the fields, having special
representations of the fields, a nasty thing. Otherwise, you use XML sealed
in the presentation layer, by packing everything under one key/value pair.
It is easy to implement, does not make sense either, typical XML.

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


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

* Re: Binary and XML serialization of types
  2014-01-24 10:01           ` Dmitry A. Kazakov
@ 2014-01-24 14:44             ` hanslad
  2014-01-24 15:22               ` Dmitry A. Kazakov
  2014-01-24 17:36             ` Simon Wright
  1 sibling, 1 reply; 34+ messages in thread
From: hanslad @ 2014-01-24 14:44 UTC (permalink / raw)


> 
> In the case 2, you should consider using packets instead of a raw octet
> 
> stream. Typically you would form an outgoing packet in the memory, using
> 
> whatever means (e.g. by a string-mapped stream) and then send the packet
> 
> out as a whole. It is especially important to do if you are going to use
> 
> NO_DELAY socket option.
> 
> 

This sounds interesting. Do you know any good examples of this? 

 
> 
> Is it a custom protocol you are going to invent? Anyway, the protocols
> 
> usually deploy some sort of packet header to describe the request and the
> 
> body of. The most efficient way is when the body length can be determined
> 
> from the header. You read the body into memory and then parse it, e.g.
> 
> using a string-mapped stream.
> 

The protocol is certanly not invented by me(OPC UA), but I want to implement it in Ada as a long term hobby project. The base types(int, IEEE-754 float) is encoded with the least significant byte appearing first (i.e. little endian).
 
> 
> > For me it would be locical to separate all the "wire information" from the
> 
> > type information. Today, the binary and xml encoding scheme is defined,
> 
> > and I had hope to be able to separate this in different packages.
> 
> 
> 
> That is doable.
> 

A simple example would be great!
As a total Ada beginner, any code examples or references to it will help me alot.

Thanks

HP


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

* Re: Binary and XML serialization of types
  2014-01-24 14:44             ` hanslad
@ 2014-01-24 15:22               ` Dmitry A. Kazakov
  2014-01-31  9:51                 ` hanslad
  0 siblings, 1 reply; 34+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-24 15:22 UTC (permalink / raw)


On Fri, 24 Jan 2014 06:44:39 -0800 (PST), hanslad@gmail.com wrote:

>> In the case 2, you should consider using packets instead of a raw octet
>> stream. Typically you would form an outgoing packet in the memory, using
>> whatever means (e.g. by a string-mapped stream) and then send the packet
>> out as a whole. It is especially important to do if you are going to use
>> NO_DELAY socket option.
> 
> This sounds interesting. Do you know any good examples of this? 

I am not sure I understand your question. Examples of what? Of the
protocols using NO_DELAY?

>> Is it a custom protocol you are going to invent? Anyway, the protocols
>> usually deploy some sort of packet header to describe the request and the
>> body of. The most efficient way is when the body length can be determined
>> from the header. You read the body into memory and then parse it, e.g.
>> using a string-mapped stream.
> 
> The protocol is certanly not invented by me(OPC UA), but I want to
> implement it in Ada as a long term hobby project. The base types(int,
> IEEE-754 float) is encoded with the least significant byte appearing first
> (i.e. little endian).

In that case you can use the implementations from Simple Components.

I cannot verify about endianness. I used OPC only once with a commercial
client from Softing GmbH. OPC is too slow and uncomfortable to use in
automation systems.

Are you going to develop an OPC server or an OPC client? Are you sure you
really want OPC? Because, for instance, an SPS can be communicated through
ModBus or ITOT, both far easier and faster than OPC.

>>> For me it would be locical to separate all the "wire information" from the
>>> type information. Today, the binary and xml encoding scheme is defined,
>>> and I had hope to be able to separate this in different packages.
>> 
>> That is doable.
> 
> A simple example would be great!

> As a total Ada beginner, any code examples or references to it will help me alot.

Well, it is not simple in general. You can take a look how Simple
Components deal with TCP/IP servers in a protocol-independent way.

http://www.dmitry-kazakov.de/ada/components.htm#multiple_GNAT.Sockets.Servers

Specifically regarding Ada, there are many ways how to handle OSI
hierarchy. Major approaches are:

1. Generics: other layers are formal parameters;
2. Inheritance, tagged types: other layers are parent or derived types;
3. Mix-in inheritance: other layers are access discriminants.

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

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

* Re: Binary and XML serialization of types
  2014-01-24  8:29       ` Oliver Kleinke
@ 2014-01-24 16:22         ` adambeneschan
  0 siblings, 0 replies; 34+ messages in thread
From: adambeneschan @ 2014-01-24 16:22 UTC (permalink / raw)


On Friday, January 24, 2014 12:29:43 AM UTC-8, Oliver Kleinke wrote:
> > What's going on is that "for Guid'Write" specifies a property, or
> 
> > "aspect"[...]
> 
> The term you were looking for is (operational) attribute.

"operational aspect" is the term used in the RM (particularly 13.1).

                                 -- Adam


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

* Re: Binary and XML serialization of types
  2014-01-24  8:44       ` Georg Bauhaus
@ 2014-01-24 17:13         ` Simon Wright
  0 siblings, 0 replies; 34+ messages in thread
From: Simon Wright @ 2014-01-24 17:13 UTC (permalink / raw)


Georg Bauhaus <rm.dash-bauhaus@futureapps.de> writes:

> On 23.01.14 20:58, hanslad@gmail.com wrote:
>> Thanks Adam,
>>
>> Ok,that makes sense.
>> One more question: Am I on the right path here, or is there a better
>> way to do binary encoding into streams? I want this to perform as
>> fast as possible.
>
> If speed is paramount and the setup permits the same representation
> of data at either end of the line, then using the Read and Write
> procedures for Stream_Element_Array is likely to be unbeatable
> (Streams.Stream_IO).
> This suggests conversion of objects of type Guid into objects of
> type Stream_Element_Array with the help of an 'Address clause or
> through an instance of Unchecked_Conversion. (And some careful
> commenting might be a good idea.)

As long as there's no awkward implementation detail in there .. for
example, GNAT's Ada.Containers.Vectors has

   type Vector is new Controlled with record
      Elements : Elements_Access;
      Last     : Extended_Index := No_Index;
      Busy     : Natural := 0;
      Lock     : Natural := 0;
   end record;

but

   procedure Write
     (Stream    : not null access Root_Stream_Type'Class;
      Container : Vector)
   is
   begin
      Count_Type'Base'Write (Stream, Length (Container));

      for J in Index_Type'First .. Container.Last loop
         Element_Type'Write (Stream, Container.Elements.EA (J));
      end loop;
   end Write;

Also, see the loop at the end of Write; Element_Type might have its own
complicated structure.

I'd say that the fact you're probably going to send the streamed data
over the wire means that speed won't be paramount. On the other hand,
you might want to minimise the number of OS interactions ...


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

* Re: Binary and XML serialization of types
  2014-01-24 10:01           ` Dmitry A. Kazakov
  2014-01-24 14:44             ` hanslad
@ 2014-01-24 17:36             ` Simon Wright
  1 sibling, 0 replies; 34+ messages in thread
From: Simon Wright @ 2014-01-24 17:36 UTC (permalink / raw)


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

> It is especially important to do if you are going to use
> NO_DELAY socket option.

And *vital* if you're going to use (GNAT's) UDP!

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9535

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

* Re: Binary and XML serialization of types
  2014-01-24 15:22               ` Dmitry A. Kazakov
@ 2014-01-31  9:51                 ` hanslad
  2014-01-31 10:49                   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 34+ messages in thread
From: hanslad @ 2014-01-31  9:51 UTC (permalink / raw)


> 
> 
> In that case you can use the implementations from Simple Components.
> 
> 


Hello,
I am sorry for the late reply on this. Y\Thank you for all the answers. 
I have looked briefly into Simple Components, and I am impressed by all the funtionalty you have implemented there.

One question: You have implemented the litle endian Unsigned_16 Get like this:

 procedure Get
             (  Data    : in out Stream_Element_Array;
                Pointer : in out Stream_Element_Offset;
                Value   : out Unsigned_16
             )  is
   begin
      if (  Pointer < Data'First
         or else
            (  Pointer > Data'Last
            and then
               Pointer > Data'Last + 1
         )  )
      then
         Raise_Exception
         (  Layout_Error'Identity,
            "Pointer is out of bounds"
         );
      elsif Pointer + 1 > Data'Last then
         Raise_Exception (End_Error'Identity, "End of data");
      end if;
      Value :=
         (  Shift_Left (Unsigned_16 (Data (Pointer + 1)), 8)
         or             Unsigned_16 (Data (Pointer))
         );
      Pointer := Pointer + 2;
   end Get;

Is it assumed that the system is little endian. How will this work on a big endian system?

Regards,

HP

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

* Re: Binary and XML serialization of types
  2014-01-31  9:51                 ` hanslad
@ 2014-01-31 10:49                   ` Dmitry A. Kazakov
  2014-02-04 10:33                     ` AdaMagica
  0 siblings, 1 reply; 34+ messages in thread
From: Dmitry A. Kazakov @ 2014-01-31 10:49 UTC (permalink / raw)


On Fri, 31 Jan 2014 01:51:37 -0800 (PST), hanslad@gmail.com wrote:

> One question: You have implemented the litle endian Unsigned_16 Get like this:
> 
>  procedure Get
>              (  Data    : in out Stream_Element_Array;
>                 Pointer : in out Stream_Element_Offset;
>                 Value   : out Unsigned_16
>              )  is
>    begin
>       if (  Pointer < Data'First
>          or else
>             (  Pointer > Data'Last
>             and then
>                Pointer > Data'Last + 1
>          )  )
>       then
>          Raise_Exception
>          (  Layout_Error'Identity,
>             "Pointer is out of bounds"
>          );
>       elsif Pointer + 1 > Data'Last then
>          Raise_Exception (End_Error'Identity, "End of data");
>       end if;
>       Value :=
>          (  Shift_Left (Unsigned_16 (Data (Pointer + 1)), 8)
>          or             Unsigned_16 (Data (Pointer))
>          );
>       Pointer := Pointer + 2;
>    end Get;
> 
> Is it assumed that the system is little endian. How will this work on a big endian system?

The number is built up from stream elements using arithmetic operations.
These operation should work regardless the endianness of the host machine.

P.S. I cannot find a reference in RM which states the semantics of
Shift_Left. I presume that it is such that

    Shift_Left (2#0001#, 1) = 2#0010#

independently on the machine endianness.

P.P.S. Conversion from Stream_Element to Unsigned_16 must also be
independent on the machine endianness. The bit-endianness of Stream_Element
must be handled by the hardware, e.g. by the Ethernet controller, when it
stores received octets into the host machine memory.

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


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

* Re: Binary and XML serialization of types
  2014-01-31 10:49                   ` Dmitry A. Kazakov
@ 2014-02-04 10:33                     ` AdaMagica
  2014-02-04 11:14                       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 34+ messages in thread
From: AdaMagica @ 2014-02-04 10:33 UTC (permalink / raw)


> P.S. I cannot find a reference in RM which states the semantics of
>
> Shift_Left. I presume that it is such that
>
>     Shift_Left (2#0001#, 1) = 2#0010#
>

B.2(9) should be clear enough, especially when you take into account the last sentence about tight shift:

For each such modular type in Interfaces, shifting and rotating subprograms as specified in the declaration of Interfaces above. These subprograms are Intrinsic. They operate on a bit-by-bit basis, using the binary representation of the value of the operands to yield a binary representation for the result. The Amount parameter gives the number of bits by which to shift or rotate. For shifting, zero bits are shifted in, except in the case of Shift_Right_Arithmetic, where one bits are shifted in if Value is at least half the modulus. 

(Note that more significant bits in any scalar value independently of its length are always left from less significant ones, independently whether you count bits from left to right (BE) or rigth to left (LE).)

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

* Re: Binary and XML serialization of types
  2014-02-04 10:33                     ` AdaMagica
@ 2014-02-04 11:14                       ` Dmitry A. Kazakov
  2014-02-04 11:20                         ` AdaMagica
  0 siblings, 1 reply; 34+ messages in thread
From: Dmitry A. Kazakov @ 2014-02-04 11:14 UTC (permalink / raw)


On Tue, 4 Feb 2014 02:33:49 -0800 (PST), AdaMagica wrote:

>> P.S. I cannot find a reference in RM which states the semantics of
>>
>> Shift_Left. I presume that it is such that
>>
>>     Shift_Left (2#0001#, 1) = 2#0010#
>>
> B.2(9) should be clear enough, especially when you take into account the
> last sentence about tight shift:
> 
> For each such modular type in Interfaces, shifting and rotating
> subprograms as specified in the declaration of Interfaces above. These
> subprograms are Intrinsic. They operate on a bit-by-bit basis, using the
> binary representation of the value of the operands to yield a binary
> representation for the result. The Amount parameter gives the number of
> bits by which to shift or rotate. For shifting, zero bits are shifted in,
> except in the case of Shift_Right_Arithmetic, where one bits are shifted
> in if Value is at least half the modulus. 
> 
> (Note that more significant bits in any scalar value independently of its
> length are always left from less significant ones, independently whether
> you count bits from left to right (BE) or rigth to left (LE).)

Yes, if "binary representation of the value" taken in its mathematical
sense. Yet in the same sentence with "bit-by-bit basis" it may leave a
[false] impression that maybe the representation here is to refer to a
representation in the physical memory, which would have a way different
meaning then.

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

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

* Re: Binary and XML serialization of types
  2014-02-04 11:14                       ` Dmitry A. Kazakov
@ 2014-02-04 11:20                         ` AdaMagica
  2014-02-04 13:04                           ` Dmitry A. Kazakov
  0 siblings, 1 reply; 34+ messages in thread
From: AdaMagica @ 2014-02-04 11:20 UTC (permalink / raw)


> Yes, if "binary representation of the value" taken in its mathematical
> sense. Yet in the same sentence with "bit-by-bit basis" it may leave a
> [false] impression that maybe the representation here is to refer to a
> representation in the physical memory, which would have a way different
> meaning then.

Hm, if I take physical memory literally, there is no direction (left, right, up, down) whatsoever in hardware, I guess.

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

* Re: Binary and XML serialization of types
  2014-02-04 11:20                         ` AdaMagica
@ 2014-02-04 13:04                           ` Dmitry A. Kazakov
  2014-02-04 17:16                             ` AdaMagica
  0 siblings, 1 reply; 34+ messages in thread
From: Dmitry A. Kazakov @ 2014-02-04 13:04 UTC (permalink / raw)


On Tue, 4 Feb 2014 03:20:16 -0800 (PST), AdaMagica wrote:

>> Yes, if "binary representation of the value" taken in its mathematical
>> sense. Yet in the same sentence with "bit-by-bit basis" it may leave a
>> [false] impression that maybe the representation here is to refer to a
>> representation in the physical memory, which would have a way different
>> meaning then.
> 
> Hm, if I take physical memory literally, there is no direction (left,
> right, up, down) whatsoever in hardware, I guess.

Left = bigger machine addresses. There are all sorts interesting questions
regarding middle-endian machines, but IMO this is a good (or bad) as left =
bigger value.

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


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

* Re: Binary and XML serialization of types
  2014-02-04 13:04                           ` Dmitry A. Kazakov
@ 2014-02-04 17:16                             ` AdaMagica
  2014-02-04 17:57                               ` Dmitry A. Kazakov
  2014-02-04 22:34                               ` Simon Wright
  0 siblings, 2 replies; 34+ messages in thread
From: AdaMagica @ 2014-02-04 17:16 UTC (permalink / raw)


> Left = bigger machine addresses.
That's why LE machines count from right to left (bytes, that is);
that's why in Ada bits are counted also right to left so that we count contiguously past byte boundaries.

> There are all sorts interesting questions
> regarding middle-endian machines, but IMO this is a good (or bad) as left =
> bigger value.

What's that, ME machines? Never heard about those.

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

* Re: Binary and XML serialization of types
  2014-02-04 17:16                             ` AdaMagica
@ 2014-02-04 17:57                               ` Dmitry A. Kazakov
  2014-02-04 22:34                               ` Simon Wright
  1 sibling, 0 replies; 34+ messages in thread
From: Dmitry A. Kazakov @ 2014-02-04 17:57 UTC (permalink / raw)


On Tue, 4 Feb 2014 09:16:04 -0800 (PST), AdaMagica wrote:

> What's that, ME machines? Never heard about those.

E.g. PDP-11. That is when endianness of one kind is used to compose words
and another to do double words etc. "Crazy" byte orders like 3412 are quite
common in automation protocols, e.g. in ModBus couplers.

ME had its reasons. Personally I found PDP-11 far easier to use than either
strictly LE x86 or strictly BE 68k.

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


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

* Re: Binary and XML serialization of types
  2014-02-04 17:16                             ` AdaMagica
  2014-02-04 17:57                               ` Dmitry A. Kazakov
@ 2014-02-04 22:34                               ` Simon Wright
  2014-02-05  9:02                                 ` AdaMagica
  1 sibling, 1 reply; 34+ messages in thread
From: Simon Wright @ 2014-02-04 22:34 UTC (permalink / raw)


AdaMagica <christ-usch.grein@t-online.de> writes:

> that's why in Ada bits are counted also right to left so that we count
> contiguously past byte boundaries.

If you are on a BE machine and you are writing a representation clause
(Ada < 2012) then, for a byte, the msb is bit 0 and the lsb is bit 7.

I'm natively little-endian, and if I'm drawing a 4-byte memory quantity
on a single line I will draw the ls byte and the ls bit within it on the
right regardless of the intended endianness. I don't know for sure what
people whose first computer was big-endian do, but I suspect it's the
same (perhaps not for people whose writing system is right-to-left) (but
see the third comment in [1], showing that at least one respected
individual thinks differently!).

So I don't see how "in Ada bits are counted [also] right to left".

[1] http://www.adacore.com/adaanswers/gems/gem-140-bridging-the-endianness-gap/

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

* Re: Binary and XML serialization of types
  2014-02-04 22:34                               ` Simon Wright
@ 2014-02-05  9:02                                 ` AdaMagica
  2014-02-05  9:39                                   ` Simon Wright
  2014-02-05 10:35                                   ` Dmitry A. Kazakov
  0 siblings, 2 replies; 34+ messages in thread
From: AdaMagica @ 2014-02-05  9:02 UTC (permalink / raw)


On Tuesday, February 4, 2014 11:34:15 PM UTC+1, Simon Wright wrote:
> AdaMagica writes:
> > that's why in Ada bits are counted also right to left so that we count
> > contiguously past byte boundaries.
> If you are on a BE machine and you are writing a representation clause
> (Ada < 2012) then, for a byte, the msb is bit 0 and the lsb is bit 7.
> I'm natively little-endian, and if I'm drawing a 4-byte memory quantity
> on a single line I will draw the ls byte and the ls bit within it on the
> right regardless of the intended endianness. I don't know for sure what
> people whose first computer was big-endian do, but I suspect it's the
> same (perhaps not for people whose writing system is right-to-left) (but
> see the third comment in [1], showing that at least one respected
> individual thinks differently!).
> So I don't see how "in Ada bits are counted [also] right to left".
> [1] http://www.adacore.com/adaanswers/gems/gem-140-bridging-the-endianness-gap/

I know this quite well, I had my deal with porting original BE code to a LE machine.

You omitted the essential part of my post: LE.
"That's why LE machines count from right to left (bytes, that is);
that's why in Ada bits are counted also right to left so that we count contiguously past byte boundaries."
On BE machines, it's the other way round of course. And that's still correct in Ada2012.

So, independently of the endianness, the MSB is always on the left. That's why Shift_Left and Shift_Right and Shift_Right_Arithmetic work the same independently of the endianness.

Now it's quite common to put the more significant digits left to the less significant ones. Chinese do it (in their pictographic digits 一二三四五六七八九十); also arabs do it (in their digits ١٢٣٤٥٦٧٨٩٠), although they write from right to left (they also say the most significant part first, except for the numbers 11 to 99, they say them like we do in German, 25 = خمسة وعشرين, hamsa wa ashrin, fünf und zwanzig, five plus twenty).

I don't know for other writing systems.

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

* Re: Binary and XML serialization of types
  2014-02-05  9:02                                 ` AdaMagica
@ 2014-02-05  9:39                                   ` Simon Wright
  2014-02-05 10:35                                   ` Dmitry A. Kazakov
  1 sibling, 0 replies; 34+ messages in thread
From: Simon Wright @ 2014-02-05  9:39 UTC (permalink / raw)


AdaMagica <christ-usch.grein@t-online.de> writes:

> On Tuesday, February 4, 2014 11:34:15 PM UTC+1, Simon Wright wrote:

>> So I don't see how "in Ada bits are counted [also] right to left".

> You omitted the essential part of my post: LE.
> "That's why LE machines count from right to left (bytes, that is);
> that's why in Ada bits are counted also right to left so that we count
> contiguously past byte boundaries."

Sorry for misreading that. To me, the way the sentence is written 'LE'
governs just 'machines'. I'd perhaps say 'that's why in Ada *running on
LE machines* bits are counted' ...

> Now it's quite common to put the more significant digits left to the
> less significant ones. Chinese do it (in their pictographic digits 一二
> 三四五六七八九十); also arabs do it (in their digits ١٢٣٤٥٦٧٨٩٠),
> although they write from right to left (they also say the most
> significant part first, except for the numbers 11 to 99, they say them
> like we do in German, 25 = خمسة وعشرين, hamsa wa ashrin, fünf und
> zwanzig, five plus twenty).

My old rugby football coach called the 25-yard line "five and twenty".


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

* Re: Binary and XML serialization of types
  2014-02-05  9:02                                 ` AdaMagica
  2014-02-05  9:39                                   ` Simon Wright
@ 2014-02-05 10:35                                   ` Dmitry A. Kazakov
  2014-02-05 13:03                                     ` AdaMagica
  1 sibling, 1 reply; 34+ messages in thread
From: Dmitry A. Kazakov @ 2014-02-05 10:35 UTC (permalink / raw)


On Wed, 5 Feb 2014 01:02:38 -0800 (PST), AdaMagica wrote:

> Now it's quite common to put the more significant digits left to the less
> significant ones. Chinese do it (in their pictographic digits 一二三四五六七八九十);
> also arabs do it (in their digits ١٢٣٤٥٦٧٨٩٠), although they write from
> right to left (they also say the most significant part first, except for
> the numbers 11 to 99, they say them like we do in German, 25 = خمسة
> وعشرين, hamsa wa ashrin, fünf und zwanzig, five plus twenty).
> 
> I don't know for other writing systems.

English, German, Russian (other European languages too?) numerals < 20 are
all LE. E.g. fifteen, fünfzig, пятнадцать = 5 + 10. It seems that numerals
start with LE and later switch to BE (when LE become inconceivable).
Germans endure LE up to 99, other peoples are less patient... (:-))

Other examples of LE, BE, ME can be found in date/time formats:

30 January 2000 (LE)
1998-02-28 (BE)
November 9, 2003 (ME)

And complements, e.g. in German

viertel vor fünf  = -00:15 + 05:00 = 04:45   (LE, complement)

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


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

* Re: Binary and XML serialization of types
  2014-02-05 10:35                                   ` Dmitry A. Kazakov
@ 2014-02-05 13:03                                     ` AdaMagica
  2014-02-05 13:44                                       ` G.B.
                                                         ` (2 more replies)
  0 siblings, 3 replies; 34+ messages in thread
From: AdaMagica @ 2014-02-05 13:03 UTC (permalink / raw)


On Wednesday, February 5, 2014 11:35:37 AM UTC+1, Dmitry A. Kazakov wrote:
> English, German, Russian (other European languages too?) numerals < 20 are
> all LE. E.g. fifteen, fünfzig, пятнадцать = 5 + 10. It seems that numerals
> start with LE and later switch to BE (when LE become inconceivable).
> Germans endure LE up to 99, other peoples are less patient... (:-))

Italien, French 11 to 16 onze, douze, ..., seize; 17 dixsept
Spanish 11 .. 15 once, doce, ... quince; 16 dieciséis

> viertel vor fünf  = -00:15 + 05:00 = 04:45   (LE, complement)
In Bavaria, we call this dreiviertel fünf, three quarters of the fifth hour,
4:15 viertel fünf, a quarter of the fifth hour.
For 4:40, you can even hear 5 Minuten vor dreiviertel fünf (five minutes to three quarters)

Not to forget about half five, this is 5:30, English speakers often omit the "past"; in German, halb fünf is 4:30 (half of the fifth hour).

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

* Re: Binary and XML serialization of types
  2014-02-05 13:03                                     ` AdaMagica
@ 2014-02-05 13:44                                       ` G.B.
  2014-02-05 15:34                                       ` Niklas Holsti
  2014-02-06  1:32                                       ` adambeneschan
  2 siblings, 0 replies; 34+ messages in thread
From: G.B. @ 2014-02-05 13:44 UTC (permalink / raw)


On 05.02.14 14:03, AdaMagica wrote:
> For 4:40, you can even hear 5 Minuten vor dreiviertel fünf (five minutes to three quarters)

Which also is (ten after half five)... I wonder if one could
dream up other names of North by Northwest, and then use them
for nibbles of a quad word?

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

* Re: Binary and XML serialization of types
  2014-02-05 13:03                                     ` AdaMagica
  2014-02-05 13:44                                       ` G.B.
@ 2014-02-05 15:34                                       ` Niklas Holsti
  2014-02-06  1:32                                       ` adambeneschan
  2 siblings, 0 replies; 34+ messages in thread
From: Niklas Holsti @ 2014-02-05 15:34 UTC (permalink / raw)


On 14-02-05 15:03 , AdaMagica wrote:
> On Wednesday, February 5, 2014 11:35:37 AM UTC+1, Dmitry A. Kazakov wrote:
>> English, German, Russian (other European languages too?) numerals < 20 are
>> all LE. E.g. fifteen, fünfzig, пятнадцать = 5 + 10. It seems that numerals
>> start with LE and later switch to BE (when LE become inconceivable).
>> Germans endure LE up to 99, other peoples are less patient... (:-))
> 
> Italien, French 11 to 16 onze, douze, ..., seize; 17 dixsept
> Spanish 11 .. 15 once, doce, ... quince; 16 dieciséis

Finnish 11 = "yksi/toista" where I use the slash to show how it is
composed of two words, "yksi" = one and "toista" = "of the second".
Meaning "one of the second set of ten". "Kaksi/toista" is 12 and so on
for 13 .. 19, then modern Finnish switches to big-endian from 20
onwards. In older text the little-endian system is sometimes continued
so that 21 can be written as "yksi/kolmatta", "one of the third set of ten".

But multiples of 10 are always in big-endian, for example 20 =
"kaksi/kymmentä" = "two tens". I assume this is because there was
originally no word for zero, so one could not express 20 as "zero of the
third set of ten".

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



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

* Re: Binary and XML serialization of types
  2014-02-05 13:03                                     ` AdaMagica
  2014-02-05 13:44                                       ` G.B.
  2014-02-05 15:34                                       ` Niklas Holsti
@ 2014-02-06  1:32                                       ` adambeneschan
  2 siblings, 0 replies; 34+ messages in thread
From: adambeneschan @ 2014-02-06  1:32 UTC (permalink / raw)


On Wednesday, February 5, 2014 5:03:19 AM UTC-8, AdaMagica wrote:

> Italien, French 11 to 16 onze, douze, ..., seize; 17 dixsept

Italian is undici, dodici, tredici, quattordici, quindici, sedici (16); then diciasette (17), ...  Same pattern as French.

                              -- Adam

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

end of thread, other threads:[~2014-02-06  1:32 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-23 18:53 Binary and XML serialization of types hanslad
2014-01-23 19:15 ` adambeneschan
2014-01-23 19:17   ` adambeneschan
2014-01-23 19:58     ` hanslad
2014-01-23 20:03       ` adambeneschan
2014-01-23 21:00       ` Dmitry A. Kazakov
2014-01-24  8:54         ` hanslad
2014-01-24 10:01           ` Dmitry A. Kazakov
2014-01-24 14:44             ` hanslad
2014-01-24 15:22               ` Dmitry A. Kazakov
2014-01-31  9:51                 ` hanslad
2014-01-31 10:49                   ` Dmitry A. Kazakov
2014-02-04 10:33                     ` AdaMagica
2014-02-04 11:14                       ` Dmitry A. Kazakov
2014-02-04 11:20                         ` AdaMagica
2014-02-04 13:04                           ` Dmitry A. Kazakov
2014-02-04 17:16                             ` AdaMagica
2014-02-04 17:57                               ` Dmitry A. Kazakov
2014-02-04 22:34                               ` Simon Wright
2014-02-05  9:02                                 ` AdaMagica
2014-02-05  9:39                                   ` Simon Wright
2014-02-05 10:35                                   ` Dmitry A. Kazakov
2014-02-05 13:03                                     ` AdaMagica
2014-02-05 13:44                                       ` G.B.
2014-02-05 15:34                                       ` Niklas Holsti
2014-02-06  1:32                                       ` adambeneschan
2014-01-24 17:36             ` Simon Wright
2014-01-24  8:44       ` Georg Bauhaus
2014-01-24 17:13         ` Simon Wright
2014-01-23 22:44   ` Simon Wright
2014-01-23 23:43     ` adambeneschan
2014-01-24  0:58       ` Randy Brukardt
2014-01-24  8:29       ` Oliver Kleinke
2014-01-24 16:22         ` adambeneschan

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