comp.lang.ada
 help / color / mirror / Atom feed
From: Natasha Kerensikova <lithiumcat@gmail.com>
Subject: Representation clauses for base-64 encoding
Date: Thu, 22 Dec 2011 09:41:30 +0000 (UTC)
Date: 2011-12-22T09:41:30+00:00	[thread overview]
Message-ID: <slrnjf5uol.1lme.lithiumcat@sigil.instinctive.eu> (raw)

Hello,

the recent discussion about representation clauses vs explicit shifting
made me wonder about what is the Right Way of performing base-64
encoding (rfc 1421).

My first thoughts were along the following lines:

   type Octet is mod 256;
      --  or Character or Storage_Element or Stream_Element
      --  or whatever 8-bit type relevant for the appliication

   for Octet'Size use 8;
   for Octet'Component_Size use 8;
   for Octet'Bit_Order use System.Low_Order_First;

   type Base_64_Digit is mod 64;

   for Base_64_Digit'Size use 6;
   for Base_64_Digit'Component_Size use 6;
   for Base_64_Digit'Bit_Order use System.Low_Order_First;

   type Octet_Block is array (1 .. 3) of Octet;
   pragma Pack (Octet_Block);

   type Base_64_Block is array (1 .. 4) of Base_64_Digit;
   pragma Pack (Base_64_Block);

   function Split_Base_64 is new Ada.Unchecked_Conversion
     (Source => Octet_Block, Target => Base_64_Block);

   function Merge_Base_64 is new Ada.Unchecked_Conversion
     (Source => Base_64_Block, Target => Octet_Block);


However, if I understand 13.3(73) correctly, conforming compilers don't
have to support such arrays (unless 6 and 8 are both factor or multiple
of word size, but I guess there are not many 2-bit or 24-bit platforms
around).

It seems a more portable but uglier way of doing it is using record:
instead of arrays:

   type Octet_Block is record
      P, Q, R : Octet;
   end record;

   for Octet_Block use record
      P at 0 range 0 .. 7;
      Q at 0 range 8 .. 15;
      R at 0 range 16 .. 23;
   end record;

   type Base_64_Block is record
      A, B, C, D : Base_64_Digit;
   end record;

   for Base_64_Block use record
      A at 0 range 0 .. 5;
      B at 0 range 6 .. 11;
      C at 0 range 12 .. 17;
      D at 0 range 18 .. 23;
   end record;

Though I guess it might not work so well in 16-bit platforms.

So is there a better way of doing it? Is it acceptable to handle
portability with different bodies for a spec that only contains the
Split_Base_64 and Merge_Base_64 functions?

Or is there some things I'm missing that makes even that non-portable or
even incorrect?


Thanks in advance for sharing your wisdom,
Natasha



             reply	other threads:[~2011-12-22  9:41 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-22  9:41 Natasha Kerensikova [this message]
2011-12-22 11:20 ` Representation clauses for base-64 encoding Niklas Holsti
2011-12-23  1:30   ` Randy Brukardt
2011-12-26  8:33     ` Niklas Holsti
2011-12-28  0:09       ` Randy Brukardt
2011-12-22 11:37 ` Georg Bauhaus
2011-12-22 12:24   ` Niklas Holsti
2011-12-22 15:09     ` Georg Bauhaus
2011-12-22 16:00       ` Natasha Kerensikova
2011-12-22 22:18         ` Georg Bauhaus
2011-12-25 10:17           ` Niklas Holsti
2011-12-27 11:23             ` Georg Bauhaus
2011-12-27 19:37               ` Niklas Holsti
2011-12-27 20:49                 ` Robert A Duff
2011-12-27 23:47                   ` Niklas Holsti
2011-12-29  0:50                     ` Robert A Duff
2011-12-30 20:54                       ` anon
2011-12-30 20:56                       ` Niklas Holsti
2011-12-23  1:42     ` Randy Brukardt
2011-12-28  8:59       ` Niklas Holsti
2011-12-29  5:41         ` Randy Brukardt
2011-12-29 10:10           ` Dmitry A. Kazakov
2011-12-23  1:33 ` Randy Brukardt
replies disabled

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