--  Reads integers, swaps nibbles, and extracts and prints characters
--  Uses a packed array of bits to swap the nibbles

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; 
with Ada.Unchecked_Conversion;
 
procedure decoding2a  is 
   type bit is mod 2;
   type Bit_Array is array(Natural range <>) of Bit with pack;
   subtype Bit_Array32 is Bit_Array(1 .. 32);

   subtype String4 is String(1 .. 4);

   function rev(s: String) return String is
      ans: String(s'range);
   begin
      for i in s'range loop
         ans(i) := s(s'first + s'last - i);  -- last shall be first
      end loop;
      return ans;
   end rev;

   function swap_nibbles(b: Bit_Array32) return Bit_Array32 is
      ( b( 5 ..  8) & b( 1 ..  4)
      & b(13 .. 16) & b( 9 .. 12)
      & b(21 .. 24) & b(17 .. 20)
      & b(29 .. 32) & b(25 .. 28));

   function int_to_Bit_Array32 is new ada.Unchecked_Conversion
      (source => Integer, target => Bit_Array32);
   function Bit_Array32_to_string4 is new ada.Unchecked_Conversion
      (source => Bit_Array32, target => String4);

   i: Integer;
   b, c: Bit_Array32;  
   s: String4;
begin
   while not end_of_file loop
      get(i);

      b := int_to_Bit_Array32(i);
      c := swap_nibbles(b);
      s := Bit_Array32_to_string4(c);

      put(rev(s));  --  Reverse because of endianess
   end loop;
end decoding2a;