-- Standalone BZip2 decoder (for .bz2 files) with BZip2.Decoding; with Ada.Text_IO; use Ada.Text_IO; with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO; with Ada.Command_Line; use Ada.Command_Line; with Interfaces; use Interfaces; procedure bunzip is f_in, f_out : Ada.Streams.Stream_IO.File_Type; type Buffer is array (Natural range <>) of Unsigned_8; -- Code with SE_Buffer below: -- workaround for the severe xxx'Read xxx'Write performance -- problems in the GNAT and ObjectAda compilers (as in 2009) -- This possible if and only if Byte = Stream_Element and -- arrays types are both packed. procedure BU_Read (b : out Buffer) is use Ada.Streams; Last : Stream_Element_Offset; SE_Buffer : Stream_Element_Array (1 .. b'Length); for SE_Buffer'Address use b'Address; pragma Import (Ada, SE_Buffer); begin -- Buffer'Read(Stream(f_in), b); -- exception -- when Ada.Streams.Stream_IO.End_Error => -- null; -- -- Nothing bad, just some garbage in the buffer -- -- after end of compressed code -- Read (Stream (f_in).all, SE_Buffer, Last); end BU_Read; procedure BU_Write (b : in Buffer) is use Ada.Streams; SE_Buffer : Stream_Element_Array (1 .. b'Length); for SE_Buffer'Address use b'Address; pragma Import (Ada, SE_Buffer); begin -- -- Buffer'Write(Stream(f_out), b); -- -- ^ Using this, instead of the lines below, more than doubles -- the whole run time (incl. decompression and slow reading!) on GNAT 2008 -- and makes +60% more time on ObjectAda 7.2.2 -- Write (Stream (f_out).all, SE_Buffer); end BU_Write; package My_BZip2 is new BZip2.Decoding ( input_buffer_size => 1024, output_buffer_size => 4096, Buffer => Buffer, check_CRC => True, Read => BU_Read, Write => BU_Write ); begin if Argument_Count = 0 then Put_Line ("Usage: bunzip "); New_Line; Put_Line ("Decompresses a bzip2 compressed file (.bz2)"); New_Line; Put_Line ("Output is written in the file: bunzip.out"); else Open (f_in, In_File, Argument (1)); Create (f_out, Out_File, "bunzip.out"); My_BZip2.Decompress; Close (f_out); end if; end bunzip;