From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,ca7e14ee1b312f90 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-04-25 19:12:06 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!arclight.uoregon.edu!wn13feed!worldnet.att.net!204.127.198.203!attbi_feed3!attbi_feed4!attbi.com!sccrnsc01.POSTED!not-for-mail From: "Steve" Newsgroups: comp.lang.ada References: Subject: Re: Minimum Record Size? LONG X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1106 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106 Message-ID: NNTP-Posting-Host: 12.211.13.75 X-Complaints-To: abuse@attbi.com X-Trace: sccrnsc01 1051323124 12.211.13.75 (Sat, 26 Apr 2003 02:12:04 GMT) NNTP-Posting-Date: Sat, 26 Apr 2003 02:12:04 GMT Organization: AT&T Broadband Date: Sat, 26 Apr 2003 02:12:04 GMT Xref: archiver1.google.com comp.lang.ada:36583 Date: 2003-04-26T02:12:04+00:00 List-Id: Here's an approach taking advantage of using "Slices" of arrays (tested w/Gnat3.15p-nt): with Ada.Text_Io; with Ada.Unchecked_Conversion; procedure Shift6to8 is type Six_Bits_Type is mod 2**6; for Six_Bits_Type'Size use 6; type Eight_Bits_Type is mod 2**8; for Eight_Bits_Type'Size use 8; package Eight_Bits_Io is new Ada.Text_Io.Modular_Io( Eight_Bits_Type ); procedure Conv_4x6_to_8x3( in1, in2, in3, in4 : Six_Bits_Type; out1, out2, out3 : out Eight_Bits_Type ) is type Bit_Array_Type is array( positive range <> ) of Boolean; pragma pack( Bit_Array_Type ); subtype Six_Bits_Array_Type is Bit_Array_Type( 1 .. 6 ); subtype Eight_Bits_Array_Type is Bit_Array_Type( 1 .. 8 ); function Conv is new Ada.Unchecked_Conversion( Six_Bits_Type, Six_Bits_Array_Type ); function Conv is new Ada.Unchecked_Conversion( Eight_Bits_Array_Type, Eight_Bits_Type ); combined : Bit_Array_Type := Conv( in1 ) & Conv( in2 ) & Conv( in3 ) & Conv( in4 ); begin out1 := Conv( combined( 1 .. 8 ) ); out2 := Conv( combined( 9 .. 16 ) ); out3 := Conv( combined( 17 .. 24 ) ); end Conv_4x6_to_8x3; sb1, sb2, sb3, sb4 : Six_Bits_Type; eb1, eb2, eb3 : Eight_Bits_Type; begin sb1 := 1; sb2 := 1; sb3 := 1; sb4 := 1; Conv_4x6_to_8x3( sb1, sb2, sb3, sb4, eb1, eb2, eb3 ); Eight_Bits_Io.Put( eb1, 4, 2 ); Ada.Text_Io.New_Line; Eight_Bits_Io.Put( eb2, 4, 2 ); Ada.Text_Io.New_Line; Eight_Bits_Io.Put( eb3, 4, 2 ); Ada.Text_Io.New_Line; end Shift6to8; "Dr Nancy's Sweetie" wrote in message news:Hrdqa.9680$io.307974@iad-read.news.verio.net... > > 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