comp.lang.ada
 help / color / mirror / Atom feed
* Generalized serialization for enumeration types
@ 2009-08-26 10:22 xorque
  2009-08-26 11:00 ` okellogg
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: xorque @ 2009-08-26 10:22 UTC (permalink / raw)


Hello.

I'm designing a package that uses a lot of similar but distinct
enumeration types.

At some point, those types need to be encoded to be sent over
the wire. The encoding rules are simple:

  The enumeration values are converted to unsigned 32 bit
  integers with the first value as 0 and increasing sequentially
  with each new value. The 32 bit value is packed into big-endian
  byte order.

The problem is: With so many enumeration types, I now have about 300
lines of almost identical procedures (to be used as stream attributes)
that just call a procedure that packs Unsigned_32 values into
Storage_Element arrays.

Is there some clever way I can just write ONE 'Write attribute
procedure
and ONE 'Read attribute procedure and have all the defined enumeration
types use those?

Freezing rules prevented me from writing a generic
Packed_Enumeration_IO
package ("representation item appears too late").



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

* Re: Generalized serialization for enumeration types
  2009-08-26 10:22 Generalized serialization for enumeration types xorque
@ 2009-08-26 11:00 ` okellogg
  2009-08-26 11:33   ` xorque
  2009-08-26 11:17 ` Georg Bauhaus
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: okellogg @ 2009-08-26 11:00 UTC (permalink / raw)


On 26 Aug., 12:22, xorque <xorquew...@googlemail.com> wrote:
> [...]
> The encoding rules are simple:
>
>   The enumeration values are converted to unsigned 32 bit
>   integers with the first value as 0 and increasing sequentially
>   with each new value.
> [...]
> Freezing rules prevented me from writing a generic
> Packed_Enumeration_IO
> package ("representation item appears too late").

If your enums are represented as you describe then why do you need
representations?
You could rely on the natural Ada representation (which happens to
conform with your encoding rules as far as the enum values are
concerned).

--Oliver



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

* Re: Generalized serialization for enumeration types
  2009-08-26 10:22 Generalized serialization for enumeration types xorque
  2009-08-26 11:00 ` okellogg
@ 2009-08-26 11:17 ` Georg Bauhaus
  2009-08-26 11:35   ` xorque
  2009-08-26 12:05 ` Dmitry A. Kazakov
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Georg Bauhaus @ 2009-08-26 11:17 UTC (permalink / raw)


xorque schrieb:
> Hello.
> 
> I'm designing a package that uses a lot of similar but distinct
> enumeration types.
> 
> At some point, those types need to be encoded to be sent over
> the wire. The encoding rules are simple:
> 
>   The enumeration values are converted to unsigned 32 bit
>   integers with the first value as 0 and increasing sequentially
>   with each new value. The 32 bit value is packed into big-endian
>   byte order.
> 
> The problem is: With so many enumeration types, I now have about 300
> lines of almost identical procedures (to be used as stream attributes)
> that just call a procedure that packs Unsigned_32 values into
> Storage_Element arrays.

Not exactly the same solution, but there doesn't seem to be
a problem with a generic and Seuqential_IO; I might well
have misunderstood.

There is a #Gem at AdaCors's web site explaining how
to use different representations for types derived from
e.g. enum types, if that is any help.

package Enums is

   type Color is (Red, Green, Blue);
   type Smell is (Good, Neutral, Bad);
private
   for Smell use (Good => 14, Neutral => 23, Bad => 100);
   for Smell'size use 32;
   for Color'size use 32;
end Enums;

generic
   type E is (<>);
procedure EG(extension : String);

with Ada.Sequential_IO;
with Interfaces;  use Interfaces;
with Ada.Unchecked_Conversion;

procedure EG(extension : String) is
   package My_IO is new Ada.Sequential_IO(Unsigned_32);
   function To_Unsigned_32 is new Ada.Unchecked_Conversion
      (Source => E, Target => Unsigned_32);
   F : My_IO.File_Type;
begin
   My_IO.Create(F, My_IO.Out_File, "run." & extension);
   for K in E loop
      My_IO.Write(F, Item => To_Unsigned_32 (K));
   end loop;
end EG;

with Enums, EG;
procedure Run is
   use Enums;
   procedure Color_Out is new EG(Color);
   procedure Smell_Out is new EG(Smell);
begin
   Color_Out("rgb");
   Smell_Out("snf");
end Run;



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

* Re: Generalized serialization for enumeration types
  2009-08-26 11:00 ` okellogg
@ 2009-08-26 11:33   ` xorque
  2009-08-26 12:03     ` okellogg
  0 siblings, 1 reply; 10+ messages in thread
From: xorque @ 2009-08-26 11:33 UTC (permalink / raw)


On Aug 26, 11:00 am, okellogg <okell...@freenet.de> wrote:
> If your enums are represented as you describe then why do you need
> representations?
> You could rely on the natural Ada representation (which happens to
> conform with your encoding rules as far as the enum values are
> concerned).

Erm. Where in the (2005) RM does it state that enums are encoded
at big-endian 32 bit integers?

xw




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

* Re: Generalized serialization for enumeration types
  2009-08-26 11:17 ` Georg Bauhaus
@ 2009-08-26 11:35   ` xorque
  0 siblings, 0 replies; 10+ messages in thread
From: xorque @ 2009-08-26 11:35 UTC (permalink / raw)


On Aug 26, 11:17 am, Georg Bauhaus <rm.dash-bauh...@futureapps.de>
wrote:
> Not exactly the same solution, but there doesn't seem to be
> a problem with a generic and Seuqential_IO; I might well
> have misunderstood.

Yes, I've seen that one (love the Gems series) but as I'm not
just writing enum values (integers, booleans, strings, etc),
I need an IO package that can handle heterogeneous data.

We're basically sending data to GNAT.Socket streams.



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

* Re: Generalized serialization for enumeration types
  2009-08-26 11:33   ` xorque
@ 2009-08-26 12:03     ` okellogg
  0 siblings, 0 replies; 10+ messages in thread
From: okellogg @ 2009-08-26 12:03 UTC (permalink / raw)


On 26 Aug., 13:33, xorque <xorquew...@googlemail.com> wrote:
> On Aug 26, 11:00 am, okellogg <okell...@freenet.de> wrote:
>
> > If your enums are represented as you describe then why do you need
> > representations?
> > You could rely on the natural Ada representation (which happens to
> > conform with your encoding rules as far as the enum values are
> > concerned).
>
> Erm. Where in the (2005) RM does it state that enums are encoded
> at big-endian 32 bit integers?
>

Perhaps I am misunderstanding - I thought along following lines:

-- file: enum_to_big_endian_unsigned32.ads
with Interfaces;
generic
   type Enum_Type is (<>);
function Enum_To_Big_Endian_Unsigned32 (Value : Enum_Type)
         return Interfaces.Unsigned_32;

-- file: enum_to_big_endian_unsigned32.adb
function Enum_To_Big_Endian_Unsigned32 (Value : Enum_Type)
         return Interfaces.Unsigned_32 is
   function htonl (host_int : Interfaces.Unsigned_32)
                   return Interfaces.Unsigned_32;
   pragma Import (C, htonl, "htonl");
begin
   return htonl (Enum_Type'Pos (Value));
end Enum_To_Big_Endian_Unsigned32;


-- file: enum2u32_test.adb - Test Main Program
with Interfaces;
with Enum_To_Big_Endian_Unsigned32;

procedure Enum2U32_Test is

   type Color_T is (Red, Green, Blue);

   function To_U32 is new Enum_To_Big_Endian_Unsigned32 (Color_T);

   Result : Interfaces.Unsigned_32 := To_U32 (Green);

begin
   -- application code ...
   null;
end;





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

* Re: Generalized serialization for enumeration types
  2009-08-26 10:22 Generalized serialization for enumeration types xorque
  2009-08-26 11:00 ` okellogg
  2009-08-26 11:17 ` Georg Bauhaus
@ 2009-08-26 12:05 ` Dmitry A. Kazakov
  2009-08-26 19:44 ` Jeffrey R. Carter
  2009-08-27  5:05 ` sjw
  4 siblings, 0 replies; 10+ messages in thread
From: Dmitry A. Kazakov @ 2009-08-26 12:05 UTC (permalink / raw)


On Wed, 26 Aug 2009 03:22:08 -0700 (PDT), xorque wrote:

> I'm designing a package that uses a lot of similar but distinct
> enumeration types.
> 
> At some point, those types need to be encoded to be sent over
> the wire. The encoding rules are simple:
> 
>   The enumeration values are converted to unsigned 32 bit
>   integers with the first value as 0 and increasing sequentially
>   with each new value. The 32 bit value is packed into big-endian
>   byte order.

We are using a chain code for same purpose. It is better for shorter values
and is not limited from above.

> The problem is: With so many enumeration types, I now have about 300
> lines of almost identical procedures (to be used as stream attributes)
> that just call a procedure that packs Unsigned_32 values into
> Storage_Element arrays.

You can read/write Enumeration_Type'Pos (Value), instead, which is how we
deal with this. The same will work with other discrete types.
 
> Is there some clever way I can just write ONE 'Write attribute procedure
> and ONE 'Read attribute procedure and have all the defined enumeration
> types use those?

No, because there is no common ancestor for these types. Another technique
we are using is that there are "comm" values of tagged types rooted in the
same abstract parent, while Get and Set operations are provided to get/set
a type-specific non-tagged value from/to. But in this case, obviously, Get
and Set must be implemented for each specific type new. Generic packages
are used for that, which then leads to a geometric explosion of instances
and an utter mess, as always when you deal with generics.

> Freezing rules prevented me from writing a generic
> Packed_Enumeration_IO
> package ("representation item appears too late").

I don't understand why. It works to us, however as I said above, a generic
solution is always bad, unless there is no any alternative. So far Ada does
not provide alternatives (like ad-hoc supertypes and interfaces etc).

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



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

* Re: Generalized serialization for enumeration types
  2009-08-26 10:22 Generalized serialization for enumeration types xorque
                   ` (2 preceding siblings ...)
  2009-08-26 12:05 ` Dmitry A. Kazakov
@ 2009-08-26 19:44 ` Jeffrey R. Carter
  2009-08-27  5:05 ` sjw
  4 siblings, 0 replies; 10+ messages in thread
From: Jeffrey R. Carter @ 2009-08-26 19:44 UTC (permalink / raw)


xorque wrote:
> 
> I'm designing a package that uses a lot of similar but distinct
> enumeration types.
> 
> At some point, those types need to be encoded to be sent over
> the wire. The encoding rules are simple:
> 
>   The enumeration values are converted to unsigned 32 bit
>   integers with the first value as 0 and increasing sequentially
>   with each new value. The 32 bit value is packed into big-endian
>   byte order.

'Pos for enumeration types gives values that satisfy this rule. They are 
universal_integer, and so may be used anywhere a value of your unsigned 32 bit 
integer type is needed.

I don't know if this helps you, however.

-- 
Jeff Carter
"If you don't get the President of the United States on that
phone, ... you're going to have to answer to the Coca-Cola
Company."
Dr. Strangelove
32



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

* Re: Generalized serialization for enumeration types
  2009-08-26 10:22 Generalized serialization for enumeration types xorque
                   ` (3 preceding siblings ...)
  2009-08-26 19:44 ` Jeffrey R. Carter
@ 2009-08-27  5:05 ` sjw
  2009-08-28 10:47   ` xorque
  4 siblings, 1 reply; 10+ messages in thread
From: sjw @ 2009-08-27  5:05 UTC (permalink / raw)


On Aug 26, 11:22 am, xorque <xorquew...@googlemail.com> wrote:
> Hello.
>
> I'm designing a package that uses a lot of similar but distinct
> enumeration types.
>
> At some point, those types need to be encoded to be sent over
> the wire. The encoding rules are simple:
>
>   The enumeration values are converted to unsigned 32 bit
>   integers with the first value as 0 and increasing sequentially
>   with each new value. The 32 bit value is packed into big-endian
>   byte order.
>
> The problem is: With so many enumeration types, I now have about 300
> lines of almost identical procedures (to be used as stream attributes)
> that just call a procedure that packs Unsigned_32 values into
> Storage_Element arrays.
>
> Is there some clever way I can just write ONE 'Write attribute
> procedure
> and ONE 'Read attribute procedure and have all the defined enumeration
> types use those?
>
> Freezing rules prevented me from writing a generic
> Packed_Enumeration_IO
> package ("representation item appears too late").

This _compiles_:

with Ada.Streams;
generic
   type E is (<>);
procedure Xorque_Writer_G (Stream : access
Ada.Streams.Root_Stream_Type'Class;
                    V : E);
procedure Xorque_Writer_G (Stream : access
Ada.Streams.Root_Stream_Type'Class;
                    V : E)
is
begin
   null;
end Xorque_Writer_G;
with Xorque_Writer_G;
package Xorque is
   type E_Base is (A, B, C);
   procedure E_Base_Writer is new Xorque_Writer_G (E_Base);
   type E is new E_Base;
   for E'Write use E_Base_Writer;
end Xorque;




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

* Re: Generalized serialization for enumeration types
  2009-08-27  5:05 ` sjw
@ 2009-08-28 10:47   ` xorque
  0 siblings, 0 replies; 10+ messages in thread
From: xorque @ 2009-08-28 10:47 UTC (permalink / raw)


Interesting. Thanks, all.

Certainly quite a bit to think about.



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

end of thread, other threads:[~2009-08-28 10:47 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-26 10:22 Generalized serialization for enumeration types xorque
2009-08-26 11:00 ` okellogg
2009-08-26 11:33   ` xorque
2009-08-26 12:03     ` okellogg
2009-08-26 11:17 ` Georg Bauhaus
2009-08-26 11:35   ` xorque
2009-08-26 12:05 ` Dmitry A. Kazakov
2009-08-26 19:44 ` Jeffrey R. Carter
2009-08-27  5:05 ` sjw
2009-08-28 10:47   ` xorque

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