comp.lang.ada
 help / color / mirror / Atom feed
* Minimum Record Size?  LONG
@ 2003-04-25 16:33 Dr Nancy's Sweetie
  2003-04-25 17:35 ` Stephen Leake
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Dr Nancy's Sweetie @ 2003-04-25 16:33 UTC (permalink / raw)



I'm working on a program which has to take four six-bit hunks of data
and regroup them into three eight-bit hunks.  My first pass looked like
this:

      Code_Value : String :=
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-";
      Clear : Unbounded_String := To_Unbounded_String("");

      Part_1     : Unsigned_32 := 0;
      Part_2     : Unsigned_32 := 0;
      Part_3     : Unsigned_32 := 0;
      Part_4     : Unsigned_32 := 0;

      Segment    : Unsigned_32 := 0;

      Val_1      : Unsigned_32;
      Val_2      : Unsigned_32;
      Val_3      : Unsigned_32;

 (some more vars and such)

      while Spot <= Coded'Last loop
         -- take four six-bit hunks
         Part_1 := Unsigned_32(Index(Code_Value, Coded(Spot  ..Spot  )) -1);
         Part_2 := Unsigned_32(Index(Code_Value, Coded(Spot+1..Spot+1)) -1);
         Part_3 := Unsigned_32(Index(Code_Value, Coded(Spot+2..Spot+2)) -1);
         Part_4 := Unsigned_32(Index(Code_Value, Coded(Spot+3..Spot+3)) -1);

         -- assemble them into one segment
         Segment := (Shift_Left(Part_1, 18) and 16#fc0000#) or
                    (Shift_Left(Part_2, 12) and 16#03f000#) or
                    (Shift_Left(Part_3,  6) and 16#000fc0#) or
                    (Shift_left(Part_4,  0) and 16#00003f#)   ;

         -- split segment into three eight-bit hunks
         Val_1 := (Shift_Right(Segment and 16#ff0000#, 16));
         Val_2 := (Shift_Right(Segment and 16#00ff00#,  8));
         Val_3 := (Shift_Right(Segment and 16#0000ff#,  0));

         -- (now do some more stuff)
      end loop;

This worked, but it seemed a little klunky.  Figuring there ought to
be a better way, I tried an Unchecked_Conversion:

      type Six_Bits is mod 2**6;
      type Four_Sixes is array (0..3) of Six_Bits;
      type Four_Group is record
         Part : Four_Sixes;
      end record;
      for Four_Group'Size use 24;

      type Eight_Bits is mod 2**8;
      type Three_Eights is array (0..2) of Eight_Bits;
      type Three_Group is record
         Part : Three_Eights;
      end record;
      for Three_Group'Size use 24;

But the compiler (gnat 3.13p) won't let me do this: it says:

    size for "Four_Group" too small, minimum allowed is 32


Well, I figure, maybe there's some array overhead that I didn't account
for.  Except that it doesn't have any problem with the Three_Group being
24 bits, and that's also an array.  But anyway, as a test, I rewrote it
like this:

      type Six_Bits is mod 2**6;
      type Four_Sixes is array (0..3) of Six_Bits;
      type Four_Group is record
         Part1, Part2, Part3, Part4 : Six_Bits;
      end record;
      for Four_Group'Size use 24;

      type Eight_Bits is mod 2**8;
      type Three_Eights is array (0..2) of Eight_Bits;
      type Three_Group is record
         Part1, Part2, Part3 : Eight_Bits;
      end record;
      for Three_Group'Size use 24;


It still won't let me do that: the minimum size for a Four_Group is
still 32 bits.  Okay, so I set the Four_Group'Size to 32.  Now it
quite reasonably complains that the sizes for my Unchecked_Conversion
are different.

My best guess at this point was that it insisted on using a full byte
to represent the Six_Bits type, but when I put in:

    for Six_Bits'Size use 6;

there was no complaint.  But four six-bit things require 32 bits to
store, even though three eight-bit things fits in 24.


When I turn on debugging (Ada.Command_Line, Getopt, and a -D switch
can save a lot of time), I discover that after the Unchecked_Conversion,
the three eight-bit elements have the exact same values as the first
three six-bit elements.  So my only guess now is that even though the
six-bit things are six bits big, they're being byte-aligned.

ANYWAY, I got to the point where I was throwing in things such as

    pragma Pack(Four_Sixes);
    for Four_Sixes'Size use 24;

And it still doesn't make any difference.  The four-element array of
six bit objects is 24 bits without a complaint, but the record still
has to be 32 bits.


So that led me to one more try: dispense with the records, and just
do an Unchecked_Conversion directly on the arrays.  The compiler is
happy with it, both array sizes are 24 bits, and the code runs without
crashing.  But the results make no sense.

If I put in C3zY, which map to 28, 55, 25, and 50, I see this:

    Put in:       28     55     25     50
              011100 110111 011001 110010

    Expect:      115      118      114
            01110011 01110110 01110010

    Actual:      220      157      201
            11011100 10011101 11001001

I can't see where the resulting bits that actually come out are from.
They don't seem to bear any relation to the bits that went in.


Suggestions?  (Yes, this can be done in C, but I'm trying to learn a
new language, not write everything in the old one.)


Darren Provine ! kilroy@elvis.rowan.edu ! http://www.rowan.edu/~kilroy
"There's nothing in human experience compared to which a sendmail config
 file could be considered simple." -- anonymous



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

end of thread, other threads:[~2003-04-28  5:04 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-25 16:33 Minimum Record Size? LONG Dr Nancy's Sweetie
2003-04-25 17:35 ` Stephen Leake
2003-04-25 17:36 ` Mark Johnson
2003-04-25 21:54   ` tmoran
2003-04-25 18:51 ` David C. Hoos
2003-04-25 21:51   ` tmoran
2003-04-26  3:00     ` David C. Hoos
2003-04-26  2:12 ` Steve
2003-04-27  1:57   ` Rick Stikkers
2003-04-27 12:06   ` David C. Hoos
2003-04-27 14:17     ` Steve
2003-04-27 20:25       ` David C. Hoos
2003-04-28  5:04         ` Steve

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