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,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-04-25 09:36:42 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!bloom-beacon.mit.edu!iad-peer.news.verio.net!news.verio.net!iad-read.news.verio.net.POSTED!not-for-mail From: Dr Nancy's Sweetie Subject: Minimum Record Size? LONG Newsgroups: comp.lang.ada Organization: Rowan University User-Agent: tin/1.4.6-20020816 ("Aerials") (UNIX) (SunOS/5.8 (sun4u)) Message-ID: Date: Fri, 25 Apr 2003 16:33:43 GMT NNTP-Posting-Host: 150.250.64.69 X-Complaints-To: abuse@verio.net X-Trace: iad-read.news.verio.net 1051288423 150.250.64.69 (Fri, 25 Apr 2003 16:33:43 GMT) NNTP-Posting-Date: Fri, 25 Apr 2003 16:33:43 GMT Xref: archiver1.google.com comp.lang.ada:36551 Date: 2003-04-25T16:33:43+00:00 List-Id: 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