home *** CD-ROM | disk | FTP | other *** search
/ Hacker / Hacker.iso / HACKER / DECOMP / DECAF / byteutil.adb < prev    next >
Encoding:
Text File  |  1996-09-19  |  16.4 KB  |  497 lines

  1. --
  2. -- Copyright (C) 1996 Ada Resource Association (ARA), Columbus, Ohio.
  3. -- Author: Gilles Demailly
  4. --
  5. --
  6. -- Permission to use, copy, modify, and distribute this software and its
  7. -- documentation for any purpose and without fee is hereby granted,
  8. -- provided that the above copyright and authorship notice appear in all
  9. -- copies and that both that copyright notice and this permission notice
  10. -- appear in supporting documentation.
  11. -- 
  12. -- The ARA makes no representations about the suitability of this software
  13. -- for any purpose.  It is provided "as is" without express
  14. -- or implied warranty.
  15. -- 
  16.  
  17. with Ada.Unchecked_Conversion;
  18.  
  19. package body Byte_Utilities is
  20.  
  21.    Mask_32 : constant Unsigned_64 := 16#FFFFFFFF#;
  22.    Mask_16 : constant Unsigned_32 := 16#FFFF#;
  23.    Mask_8  : constant Unsigned_16 := 16#FF#;
  24.    
  25.    --
  26.    -- Unchecked conversion is used to convert bytes to
  27.    -- the differents types declared in Basic_Definitions
  28.    --
  29.    function To_Integer  is new Ada.Unchecked_Conversion
  30.                                   (Unsigned_8, Integer_8);
  31.    function To_Integer  is new Ada.Unchecked_Conversion
  32.                                   (Unsigned_16, Integer_16);
  33.    function To_Integer  is new Ada.Unchecked_Conversion
  34.                                   (Unsigned_32, Integer_32);
  35.    function To_Integer  is new Ada.Unchecked_Conversion
  36.                                   (Unsigned_64, Integer_64);
  37.    function To_Unsigned is new Ada.Unchecked_Conversion
  38.                                   (Integer_8, Unsigned_8);
  39.    function To_Unsigned is new Ada.Unchecked_Conversion
  40.                                   (Integer_16, Unsigned_16);
  41.    function To_Unsigned is new Ada.Unchecked_Conversion
  42.                                   (Integer_32, Unsigned_32);
  43.    function To_Unsigned is new Ada.Unchecked_Conversion
  44.                                   (Integer_64, Unsigned_64);
  45.    function To_Unsigned is new Ada.Unchecked_Conversion
  46.                                   (Float_32, Unsigned_32);
  47.    function To_Unsigned is new Ada.Unchecked_Conversion
  48.                                   (Float_64, Unsigned_64);
  49.    function To_Float    is new Ada.Unchecked_Conversion
  50.                                   (Unsigned_32, Float_32);
  51.    function To_Float    is new Ada.Unchecked_Conversion
  52.                                   (Unsigned_64, Float_64);
  53.    
  54.    
  55.    -- conversion to file_mode declared in Sequential_Io
  56.    ----------------------------------------------------
  57.    function To_File_Mode (Mode : File_Mode) return Byte_Io.File_Mode is
  58.    begin
  59.       case Mode is
  60.          when In_File =>
  61.             return Byte_Io.In_File;
  62.          when Out_File =>
  63.             return Byte_Io.Out_File;
  64.          when Append_File =>
  65.             return Byte_Io.Append_File;
  66.       end case;
  67.    end To_File_Mode;
  68.  
  69.    --
  70.    -- basic services just make a call to the Sequential_Io 
  71.    -- instanciation services
  72.    --
  73.       
  74.    procedure Create (File       : in out File_Type;
  75.                      Mode       : in File_Mode         := Out_File;
  76.                      Byte_Order : in Byte_Order_Scheme := Big_Endian;
  77.                      Name       : in String) is
  78.    begin
  79.       File.Byte_Order := Byte_Order;
  80.       Byte_Io.Create (File.File, To_File_Mode (Mode), Name);
  81.    end Create;
  82.    
  83.    procedure Open   (File       : in out File_Type;
  84.                      Mode       : in File_Mode;
  85.                      Byte_Order : in Byte_Order_Scheme;
  86.                      Name       : in String) is
  87.    begin
  88.       File.Byte_Order := Byte_Order;
  89.       Byte_Io.Open (File.File, To_File_Mode (Mode), Name);
  90.    end Open;
  91.  
  92.    procedure Close  (File : in out File_Type) is
  93.    begin
  94.       Byte_Io.Close (File.File);
  95.    end Close;
  96.  
  97.    procedure Delete (File : in out File_Type) is
  98.    begin
  99.       Byte_Io.Delete (File.File);
  100.    end Delete;
  101.    
  102.    procedure Reset  (File       : in out File_Type;
  103.                      Mode       : in File_mode;
  104.                      Byte_Order : in Byte_Order_Scheme) is
  105.    begin
  106.       Byte_Io.Reset (File.File, To_File_Mode (Mode));
  107.       File.Byte_Order := Byte_Order;
  108.    end Reset;
  109.  
  110.    procedure Reset  (File : in out File_Type) is
  111.    begin
  112.       Byte_Io.Reset (File.File);
  113.    end Reset;
  114.    
  115.    
  116.    --
  117.    -- Read procedures for types defined in Basic_Definitions
  118.    -- types sized other 8 bits receive special treatment depending
  119.    -- on the underlying representation of data in the file
  120.    --
  121.    
  122.    procedure Read   (File : in File_Type; Item : out Unsigned_8) is
  123.    begin
  124.       Byte_Io.Read (File.File, Item);
  125.    end Read;
  126.    
  127.    procedure Read   (File : in File_Type; Item : out Unsigned_16) is
  128.       Part   : Unsigned_8;
  129.       Answer : Unsigned_16;
  130.    begin
  131.       Byte_Io.Read (File.File, Part);
  132.       case File.Byte_Order is
  133.          when Big_Endian =>
  134.             Answer := Shift_Left (Unsigned_16 (Part), 8);
  135.          when Little_Endian =>
  136.             Answer := Unsigned_16 (Part);
  137.       end case;
  138.       Byte_Io.Read (File.File, Part);
  139.       case File.Byte_Order is
  140.          when Big_Endian =>
  141.             Answer := Answer + Unsigned_16 (Part);
  142.          when Little_Endian =>
  143.             Answer := Answer + Shift_Left (Unsigned_16 (Part), 8);
  144.       end case;
  145.       Item := Answer;
  146.    end Read;
  147.    
  148.    procedure Read   (File : in File_Type; Item : out Unsigned_32) is
  149.       Part   : Unsigned_16;
  150.       Answer : Unsigned_32;
  151.    begin
  152.       Read (File, Part);
  153.       case File.Byte_Order is
  154.          when Big_Endian =>
  155.             Answer := Shift_Left (Unsigned_32 (Part), 16);
  156.          when Little_Endian =>
  157.             Answer := Unsigned_32 (Part);
  158.       end case;
  159.       Read (File, Part);
  160.       case File.Byte_Order is
  161.          when Big_Endian =>
  162.             Answer := Answer + Unsigned_32 (Part);
  163.          when Little_Endian =>
  164.             Answer := Answer + Shift_Left (Unsigned_32 (Part), 16);
  165.       end case;
  166.       Item := Answer;
  167.    end Read;
  168.    
  169.    procedure Read   (File : in File_Type; Item : out Unsigned_64) is
  170.       Part   : Unsigned_32;
  171.       Answer : Unsigned_64;
  172.    begin
  173.       Read (File, Part);
  174.       case File.Byte_Order is
  175.          when Big_Endian =>
  176.             Answer := Shift_Left (Unsigned_64 (Part), 32);
  177.          when Little_Endian =>
  178.             Answer := Unsigned_64 (Part);
  179.       end case;
  180.       Read (File, Part);
  181.       case File.Byte_Order is
  182.          when Big_Endian =>
  183.             Answer := Answer + Unsigned_64 (Part);
  184.          when Little_Endian =>
  185.             Answer := Answer + Shift_Left (Unsigned_64 (Part), 32);
  186.       end case;
  187.       Item := Answer;
  188.    end Read;
  189.    
  190.    procedure Read   (File : in File_Type; Item : out Integer_8) is
  191.       Answer : Unsigned_8;
  192.    begin
  193.       Read (File, Answer);
  194.       Item := To_Integer (Answer);
  195.    end Read;
  196.    
  197.    procedure Read   (File : in File_Type; Item : out Integer_16) is
  198.       Answer : Unsigned_16;
  199.    begin
  200.       Read (File, Answer);
  201.       Item := To_Integer (Answer);
  202.    end Read;
  203.    
  204.    procedure Read   (File : in File_Type; Item : out Integer_32) is
  205.       Answer : Unsigned_32;
  206.    begin
  207.       Read (File, Answer);
  208.       Item := To_Integer (Answer);
  209.    end Read;
  210.    
  211.    procedure Read   (File : in File_Type; Item : out Integer_64) is
  212.       Answer : Unsigned_64;
  213.    begin
  214.       Read (File, Answer);
  215.       Item := To_Integer (Answer);
  216.    end Read;
  217.    
  218.    procedure Read   (File : in File_Type; Item : out Float_32) is
  219.       Answer : Unsigned_32;
  220.    begin
  221.       Read (File, Answer);
  222.       Item := To_Float (Answer);
  223.    end Read;
  224.    
  225.    procedure Read   (File : in File_Type; Item : out Float_64) is
  226.       Answer : Unsigned_64;
  227.    begin
  228.       Read (File, Answer);
  229.       Item := To_Float (Answer);
  230.    end Read;
  231.    
  232.    
  233.    --
  234.    -- Write procedures for types defined in Basic_Definitions
  235.    -- types sized other 8 bits receive special treatment depending
  236.    -- on the underlying representation of data in the file
  237.    --
  238.    
  239.    procedure Write  (File : in File_Type; Item : in Unsigned_8) is
  240.    begin
  241.       Byte_Io.Write (File.File, Item);
  242.    end Write;
  243.    
  244.    procedure Write  (File : in File_Type; Item : in Unsigned_16) is
  245.       Part : Unsigned_8;
  246.    begin
  247.       case File.Byte_Order is
  248.          when Big_Endian =>
  249.             Part := Unsigned_8 (Shift_Right (Item, 8) and Mask_8);
  250.          when Little_Endian =>
  251.             Part := Unsigned_8 (Item and Mask_8);
  252.       end case;
  253.       Byte_Io.Write (File.File, Part);
  254.       case File.Byte_Order is
  255.          when Big_Endian =>
  256.             Part := Unsigned_8 (Item and Mask_8);
  257.          when Little_Endian =>
  258.             Part := Unsigned_8 (Shift_Right (Item, 8) and Mask_8);
  259.       end case;
  260.       Byte_Io.Write (File.File, Part);
  261.    end Write;
  262.    
  263.    procedure Write  (File : in File_Type; Item : in Unsigned_32) is
  264.       Part : Unsigned_16;
  265.    begin
  266.       case File.Byte_Order is
  267.          when Big_Endian =>
  268.             Part := Unsigned_16 (Shift_Right (Item, 16) and Mask_16);
  269.          when Little_Endian =>
  270.             Part := Unsigned_16 (Item and Mask_16);
  271.       end case;
  272.       Write (File, Part);
  273.       case File.Byte_Order is
  274.          when Big_Endian =>
  275.             Part := Unsigned_16 (Item and Mask_16);
  276.          when Little_Endian =>
  277.             Part := Unsigned_16 (Shift_Right (Item, 16) and Mask_16);
  278.       end case;
  279.       Write (File, Part);
  280.    end Write;
  281.    
  282.    procedure Write  (File : in File_Type; Item : in Unsigned_64) is
  283.       Part : Unsigned_32;
  284.    begin
  285.       case File.Byte_Order is
  286.          when Big_Endian =>
  287.             Part := Unsigned_32 (Shift_Right (Item, 32) and Mask_32);
  288.          when Little_Endian =>
  289.             Part := Unsigned_32 (Item and Mask_32);
  290.       end case;
  291.       Write (File, Part);
  292.       case File.Byte_Order is
  293.          when Big_Endian =>
  294.             Part := Unsigned_32 (Item and Mask_32);
  295.          when Little_Endian =>
  296.             Part := Unsigned_32 (Shift_Right (Item, 32) and Mask_32);
  297.       end case;
  298.       Write (File, Part);
  299.    end Write;
  300.    
  301.    procedure Write  (File : in File_Type; Item : in Integer_8) is
  302.    begin
  303.       Write (File, To_Unsigned (Item));
  304.    end Write;
  305.    
  306.    procedure Write  (File : in File_Type; Item : in Integer_16) is
  307.    begin
  308.       Write (File, To_Unsigned (Item));
  309.    end Write;
  310.    
  311.    procedure Write  (File : in File_Type; Item : in Integer_32) is
  312.    begin
  313.       Write (File, To_Unsigned (Item));
  314.    end Write;
  315.    
  316.    procedure Write  (File : in File_Type; Item : in Integer_64) is
  317.    begin
  318.       Write (File, To_Unsigned (Item));
  319.    end Write;
  320.    
  321.    procedure Write  (File : in File_Type; Item : in Float_32) is
  322.    begin
  323.       Write (File, To_Unsigned (Item));
  324.    end Write;
  325.    
  326.    procedure Write  (File : in File_Type; Item : in Float_64) is
  327.    begin
  328.       Write (File, To_Unsigned (Item));
  329.    end Write;
  330.    
  331.    
  332.    --
  333.    -- Read functions for types defined in Basic_Definitions
  334.    -- types sized other 8 bits receive special treatment depending
  335.    -- on the underlying representation of data in the file
  336.    --
  337.    
  338.    function Get_Unsigned_8
  339.                (From       : Acc_Bytes;
  340.                 Index      : Unsigned_32)
  341.             return Unsigned_8 is
  342.    begin
  343.       return From (Index);
  344.    end Get_Unsigned_8;
  345.    
  346.    function Get_Unsigned_16
  347.                (From       : Acc_Bytes;
  348.                 Index      : Unsigned_32;
  349.                 Byte_Order : Byte_Order_Scheme := Big_Endian)
  350.             return Unsigned_16 is
  351.       Answer : Unsigned_16; 
  352.    begin
  353.       case Byte_Order is
  354.          when Big_Endian =>
  355.             Answer := Shift_Left (Unsigned_16 (From (Index)), 8);
  356.             Answer := Answer + Unsigned_16 (From (Index + 1));
  357.          when Little_Endian =>
  358.             Answer := Shift_Left (Unsigned_16 (From (Index + 1)), 8);
  359.             Answer := Answer + Unsigned_16 (From (Index));
  360.       end case;
  361.       return Answer;
  362.    end Get_Unsigned_16;
  363.  
  364.    function Get_Unsigned_32
  365.                (From       : Acc_Bytes;
  366.                 Index      : Unsigned_32;
  367.                 Byte_Order : Byte_Order_Scheme := Big_Endian)
  368.             return Unsigned_32 is
  369.       Answer : Unsigned_32; 
  370.    begin
  371.       case Byte_Order is
  372.          when Big_Endian =>
  373.             Answer := Shift_Left (Unsigned_32 (From (Index)), 24);
  374.             Answer := Answer + Shift_Left (Unsigned_32 (From (Index + 1)), 16);
  375.             Answer := Answer + Shift_Left (Unsigned_32 (From (Index + 2)), 8);
  376.             Answer := Answer + Unsigned_32 (From (Index + 3));
  377.          when Little_Endian =>
  378.             Answer := Shift_Left (Unsigned_32 (From (Index + 3)), 24);
  379.             Answer := Answer + Shift_Left (Unsigned_32 (From (Index + 2)), 16);
  380.             Answer := Answer + Shift_Left (Unsigned_32 (From (Index + 1)), 8);
  381.             Answer := Answer + Unsigned_32 (From (Index));
  382.       end case;
  383.       return Answer;
  384.    end Get_Unsigned_32;
  385.  
  386.    function Get_Unsigned_64
  387.                (From       : Acc_Bytes;
  388.                 Index      : Unsigned_32;
  389.                 Byte_Order : Byte_Order_Scheme := Big_Endian)
  390.             return Unsigned_64 is
  391.       Answer : Unsigned_64; 
  392.    begin
  393.       case Byte_Order is
  394.          when Big_Endian =>
  395.             Answer := Shift_Left (Unsigned_64 (From (Index)), 56);
  396.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 1)), 48);
  397.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 2)), 40);
  398.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 3)), 32);
  399.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 4)), 24);
  400.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 5)), 16);
  401.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 6)), 8);
  402.             Answer := Answer + Unsigned_64 (From (Index + 7));
  403.          when Little_Endian =>
  404.             Answer := Shift_Left (Unsigned_64 (From (Index + 7)), 56);
  405.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 6)), 48);
  406.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 5)), 40);
  407.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 4)), 32);
  408.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 3)), 24);
  409.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 2)), 16);
  410.             Answer := Answer + Shift_Left (Unsigned_64 (From (Index + 1)), 8);
  411.             Answer := Answer + Unsigned_64 (From (Index));
  412.       end case;
  413.       return Answer;
  414.    end Get_Unsigned_64;
  415.  
  416.  
  417.    function Get_Float_32
  418.                (From       : Acc_Bytes;
  419.                 Index      : Unsigned_32;
  420.                 Byte_Order : Byte_Order_Scheme := Big_Endian)
  421.             return Float_32 is
  422.       Answer : Unsigned_32; 
  423.    begin
  424.       Answer := Get_Unsigned_32
  425.                    (From       => From,
  426.                     Index      => Index,
  427.                     Byte_Order => Byte_Order);
  428.       return To_Float (Answer);
  429.    end Get_Float_32;
  430.  
  431.    function Get_Float_64
  432.                (From       : Acc_Bytes;
  433.                 Index      : Unsigned_32;
  434.                 Byte_Order : Byte_Order_Scheme := Big_Endian)
  435.             return Float_64 is
  436.       Answer : Unsigned_64; 
  437.    begin
  438.       Answer := Get_Unsigned_64
  439.                    (From       => From,
  440.                     Index      => Index,
  441.                     Byte_Order => Byte_Order);
  442.       return To_Float (Answer);
  443.    end Get_Float_64;
  444.  
  445.  
  446.    function Get_Integer_8
  447.                (From       : Acc_Bytes;
  448.                 Index      : Unsigned_32)
  449.             return Integer_8 is
  450.    begin
  451.       return To_Integer (Get_Unsigned_8 (From, Index));
  452.    end Get_Integer_8;
  453.  
  454.    function Get_Integer_16
  455.                (From       : Acc_Bytes;
  456.                 Index      : Unsigned_32;
  457.                 Byte_Order : Byte_Order_Scheme := Big_Endian)
  458.             return Integer_16 is
  459.    begin
  460.       return To_Integer (Get_Unsigned_16 (From, Index, Byte_Order));
  461.    end Get_Integer_16;
  462.  
  463.    function Get_Integer_32
  464.                (From       : Acc_Bytes;
  465.                 Index      : Unsigned_32;
  466.                 Byte_Order : Byte_Order_Scheme := Big_Endian)
  467.             return Integer_32 is
  468.    begin
  469.       return To_Integer (Get_Unsigned_32 (From, Index, Byte_Order));
  470.    end Get_Integer_32;
  471.  
  472.    function Get_Integer_64
  473.                (From       : Acc_Bytes;
  474.                 Index      : Unsigned_32;
  475.                 Byte_Order : Byte_Order_Scheme := Big_Endian)
  476.             return Integer_64 is
  477.    begin
  478.       return To_Integer (Get_Unsigned_64 (From, Index, Byte_Order));
  479.    end Get_Integer_64;
  480.  
  481.    function Get_String
  482.                (From   : Acc_Bytes;
  483.                 Index  : Unsigned_32;
  484.                 Length : Positive)
  485.             return String is
  486.  
  487.       subtype String_Loc is String (1..Length);
  488.       subtype Bytes_Loc is  Bytes  (1..Unsigned_32(Length));
  489.       
  490.       function To_String is new Ada.Unchecked_Conversion
  491.                                    (Bytes_Loc, String_Loc);
  492.    begin
  493.       return To_String (From.all (Index .. Index + Unsigned_32(Length) - 1));
  494.    end Get_String;
  495.  
  496. end Byte_Utilities;
  497.