comp.lang.ada
 help / color / mirror / Atom feed
* Advice Please
@ 2006-11-10  6:52 laehyung
  2006-11-10  9:27 ` Dmitry A. Kazakov
  2006-11-10 20:32 ` Jeffrey R. Carter
  0 siblings, 2 replies; 3+ messages in thread
From: laehyung @ 2006-11-10  6:52 UTC (permalink / raw)


Advice & comments please.
my test code is ...

with Ada.Text_IO; use Ada.Text_IO;

with Ada.Characters.Handling;
use Ada.Characters.Handling;
with Ada.Unchecked_Conversion;
with Interfaces;   use Interfaces;
with Interfaces.C;

procedure Test_Str is

---------------------------------------
   function Conv_U8_To_Char is
      new Ada.Unchecked_Conversion(Source => Unsigned_8,
      	                           Target => Character);
   function Conv_Char_To_U8 is
      new Ada.Unchecked_Conversion(Source => Character,
      	                           Target => Unsigned_8);

---------------------------------------

   function Strhex_To_Ascii_Strbyte (Item : in String) return String is

      Strsize    : Natural  := Item'Length;
      Rtn_Length : Natural  := (Strsize)/2;

      Str_Val    : String(1..Rtn_Length);

      Strtemp1 : Unsigned_8;
      Strtemp2 : Unsigned_8;
      C        : array(1..Strsize) of Unsigned_8;

   begin

      for Idx in Item'range loop
         if Is_Hexadecimal_Digit(Item(Idx)) then
            if Is_Digit(Item(Idx)) then
               C(Idx):=
Unsigned_8(Character'Pos(Item(Idx))-Character'Pos('0'));
            else
               C(Idx):= Unsigned_8(Character'Pos(To_Upper(Item(Idx)))
                     -Character'Pos('A')+16#A#);
            end if;
         else
            Put_Line("Program Code contains NON-HexaDecimal character.
program Break");
            raise Data_Error;
         end if;
      end loop;

      for I in 1..Rtn_Length loop
         Strtemp1 := Shift_Left(Unsigned_8(C(2*I-1)),4) and
Unsigned_8(16#FF#);
         Strtemp2 := Unsigned_8(C(2*I)) and Unsigned_8(16#FF#);

         Str_Val(I) := Conv_U8_To_Char( Strtemp1 or Strtemp2 );

      end loop;

      return Str_Val;
   end Strhex_To_Ascii_Strbyte;
---------------------------------------


   Input_Str : String := "0000002D0F010000002E0F000000000A10A3";

begin

   --Put("Output_Str =>");
   Put(Strhex_To_Ascii_Strbyte(Input_Str));

end Test_Str;

----------------------------------------------------------------
(my machine is windows XP)
Compile & Run:

c:\work>gnatmke -O2 -gnatvf test_str
gcc -c -O2 -gnatvf test_str.adb

GNAT GPL 2006 (20060522-34)
Copyright 1992-2006, Free Software Foundation, Inc.

Compiling: test_str.adb (source file time stamp: 2006-11-10 05:22:28)
 68 lines: No errors
gnatbind -x test_str.ali
gnatlink test_str.ali

c:\work> test_str > code_test.txt

edit code_test.txt file with hexa code editor(ex. UltraEdit-32)

output data shold be
00000000h:00 00 00 2D 0F 01 00 00 00 2E 0F 00 00 00 00 00
;...-............
00000010h:0A 10 A3 0D 0A                                  ;..?.

but result is
00000000h:00 00 00 2D 0F 01 00 00 00 2E 0F 00 00 00 00 0D
;...-............
00000010h:0A 10 A3 0D 0A                                  ;..?.

the data of address 0Fh is 0D, why?
How to correct this problem.




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

* Re: Advice Please
  2006-11-10  6:52 Advice Please laehyung
@ 2006-11-10  9:27 ` Dmitry A. Kazakov
  2006-11-10 20:32 ` Jeffrey R. Carter
  1 sibling, 0 replies; 3+ messages in thread
From: Dmitry A. Kazakov @ 2006-11-10  9:27 UTC (permalink / raw)


On 9 Nov 2006 22:52:15 -0800, laehyung wrote:

> Advice & comments please.
> my test code is ...
> 
> with Ada.Text_IO; use Ada.Text_IO;
> 
> with Ada.Characters.Handling;
> use Ada.Characters.Handling;
> with Ada.Unchecked_Conversion;
> with Interfaces;   use Interfaces;
> with Interfaces.C;
> 
> procedure Test_Str is
> 
> ---------------------------------------
>    function Conv_U8_To_Char is
>       new Ada.Unchecked_Conversion(Source => Unsigned_8,
>       	                           Target => Character);
>    function Conv_Char_To_U8 is
>       new Ada.Unchecked_Conversion(Source => Character,
>       	                           Target => Unsigned_8);
> 
> ---------------------------------------
> 
>    function Strhex_To_Ascii_Strbyte (Item : in String) return String is
> 
>       Strsize    : Natural  := Item'Length;
>       Rtn_Length : Natural  := (Strsize)/2;
> 
>       Str_Val    : String(1..Rtn_Length);
> 
>       Strtemp1 : Unsigned_8;
>       Strtemp2 : Unsigned_8;
>       C        : array(1..Strsize) of Unsigned_8;
> 
>    begin
> 
>       for Idx in Item'range loop
>          if Is_Hexadecimal_Digit(Item(Idx)) then
>             if Is_Digit(Item(Idx)) then
>                C(Idx):=
> Unsigned_8(Character'Pos(Item(Idx))-Character'Pos('0'));
>             else
>                C(Idx):= Unsigned_8(Character'Pos(To_Upper(Item(Idx)))
>                      -Character'Pos('A')+16#A#);
>             end if;
>          else
>             Put_Line("Program Code contains NON-HexaDecimal character.
> program Break");
>             raise Data_Error;
>          end if;
>       end loop;
> 
>       for I in 1..Rtn_Length loop
>          Strtemp1 := Shift_Left(Unsigned_8(C(2*I-1)),4) and
> Unsigned_8(16#FF#);
>          Strtemp2 := Unsigned_8(C(2*I)) and Unsigned_8(16#FF#);
> 
>          Str_Val(I) := Conv_U8_To_Char( Strtemp1 or Strtemp2 );
> 
>       end loop;
> 
>       return Str_Val;
>    end Strhex_To_Ascii_Strbyte;
> ---------------------------------------
> 
> 
>    Input_Str : String := "0000002D0F010000002E0F000000000A10A3";
> 
> begin
> 
>    --Put("Output_Str =>");
>    Put(Strhex_To_Ascii_Strbyte(Input_Str));
> 
> end Test_Str;
> 
> ----------------------------------------------------------------
> (my machine is windows XP)
> Compile & Run:
> 
> c:\work>gnatmke -O2 -gnatvf test_str
> gcc -c -O2 -gnatvf test_str.adb
> 
> GNAT GPL 2006 (20060522-34)
> Copyright 1992-2006, Free Software Foundation, Inc.
> 
> Compiling: test_str.adb (source file time stamp: 2006-11-10 05:22:28)
>  68 lines: No errors
> gnatbind -x test_str.ali
> gnatlink test_str.ali
> 
> c:\work> test_str > code_test.txt
> 
> edit code_test.txt file with hexa code editor(ex. UltraEdit-32)
> 
> output data shold be
> 00000000h:00 00 00 2D 0F 01 00 00 00 2E 0F 00 00 00 00 00
> ;...-............
> 00000010h:0A 10 A3 0D 0A                                  ;..?.

No, it should not. I should be (in a binary output mode):

00 00 00 2D 0F 01 00 00 00 2E 0F 00 00 00 00 0A 10 A3

four zeros before the last triplet. Note also that when you write a text
file the OS may translate formatters (like LF and CR). That explains the
effect you've got. 0A was translated into 0D 0A pair.

> but result is
> 00000000h:00 00 00 2D 0F 01 00 00 00 2E 0F 00 00 00 00 0D
> ;...-............
> 00000010h:0A 10 A3 0D 0A                                  ;..?.
> 
> the data of address 0Fh is 0D, why?
> How to correct this problem.

There is no problem, your code works.

Admittedly, the code needs much rework both in terms of efficiency and
clarity. Use case statement for character classification or else a
translation map. You don't need the array C, everything can be done in one
pass. You don't need modular arithmetic and masking. Use integer
multiplication and addition. Use 'Val attribute instead of
Unchecked_Conversion. What would be the result for an odd-length string?

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



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

* Re: Advice Please
  2006-11-10  6:52 Advice Please laehyung
  2006-11-10  9:27 ` Dmitry A. Kazakov
@ 2006-11-10 20:32 ` Jeffrey R. Carter
  1 sibling, 0 replies; 3+ messages in thread
From: Jeffrey R. Carter @ 2006-11-10 20:32 UTC (permalink / raw)


laehyung wrote:
> 
> ---------------------------------------
>    function Conv_U8_To_Char is
>       new Ada.Unchecked_Conversion(Source => Unsigned_8,
>       	                           Target => Character);

Character'Val does the same thing.

>    function Conv_Char_To_U8 is
>       new Ada.Unchecked_Conversion(Source => Character,
>       	                           Target => Unsigned_8);

Character'Pos does the same thing.

>                C(Idx):=
> Unsigned_8(Character'Pos(Item(Idx))-Character'Pos('0'));

No conversion should be necessary. Character'Pos returns a universal 
integer, which is implicitly converted.

>          Strtemp1 := Shift_Left(Unsigned_8(C(2*I-1)),4) and
> Unsigned_8(16#FF#);

No conversions are necessary. C (...) is already of type Unsigned_8, and 
16#FF#, an integer literal, may be used with any integer type without 
conversion.

-- 
Jeff Carter
"Go and boil your bottoms."
Monty Python & the Holy Grail
01



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

end of thread, other threads:[~2006-11-10 20:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-11-10  6:52 Advice Please laehyung
2006-11-10  9:27 ` Dmitry A. Kazakov
2006-11-10 20:32 ` Jeffrey R. Carter

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