1. --  ________  ___   ______       ______     ___ 
  2.  -- /___ .. ._/  |.|   |.___.\     /. __ .\  __|.|   ____ 
  3.  --    / .. /    |.|   |.____/     |.|__|.| / .. ..|  __\ .. \ 
  4.  --  _/ .. /___  |.|   |.|    ===  | .. __ .. ||. = .| | = .. | 
  5.  -- /_______/  |_|  /__|        /__|  |_| \__\_|  \__\_| 
  6.  
  7.  -- This package provides: 
  8.  -- 
  9.  -- * Definiton of PKZIP information structures (cf appnote.txt), 
  10.  -- * Reading a header from a data stream (Read_and_check), 
  11.  -- * Copying a header from a buffer (Copy_and_check) 
  12.  -- * Writing a header to a data stream (Write) 
  13.  
  14.  -- Change log: 
  15.  -- ========== 
  16.  -- 16 - Nov - 2009 : GdM : Replaced Ada.Calendar.Time by Zip.Time in headers, due to 
  17.  --                   perf. issues in some run - times' Ada.Calendar.Time_Of 
  18.  
  19. with Interfaces; 
  20. with Zip_Streams;  use Zip_Streams; 
  21.  
  22. package Zip.Headers is 
  23.  
  24.   use Interfaces; 
  25.  
  26.   ---------------------------------------------------------------------- 
  27.   -- PKZIP data descriptor, put after streamed compressed data - PK78 -- 
  28.   ---------------------------------------------------------------------- 
  29.  
  30.   type Data_descriptor is record 
  31.     -- PK78                            --  1 .. 4 
  32.     crc_32              : Unsigned_32; --  5 .. 8 
  33.     compressed_size, 
  34.     uncompressed_size   : Unsigned_32; 
  35.   end record; 
  36.  
  37.   data_descriptor_length  : constant := 16; 
  38.  
  39.   -- This header needs to be read in continuation of 
  40.   -- the compressed data - > access to a buffer 
  41.   procedure Copy_and_check (buffer        :     Byte_Buffer; 
  42.                             the_data_desc : out Data_descriptor); 
  43.  
  44.    procedure Read_and_check (stream        :     Zipstream_Class; 
  45.                              the_data_desc : out Data_descriptor); 
  46.  
  47.   bad_data_descriptor : exception; 
  48.  
  49.   procedure Write (stream        : Zipstream_Class; 
  50.                    the_data_desc : Data_descriptor); 
  51.  
  52.   ----------------------------------------------------------------------- 
  53.   -- PKZIP local file header, in front of every file in archive - PK34 -- 
  54.   ----------------------------------------------------------------------- 
  55.  
  56.   Language_Encoding_Flag_Bit  : constant := 2**11; 
  57.  
  58.   type Local_File_Header is record 
  59.     -- PK34                                 --  1 .. 4 
  60.     needed_extract_version  : Unsigned_16;  --  5 .. 6 
  61.     bit_flag, 
  62.     zip_type                : Unsigned_16; 
  63.     file_timedate           : Time; 
  64.     dd                      : Data_descriptor; 
  65.     filename_length, 
  66.     extra_field_length      : Unsigned_16; 
  67.   end record; 
  68.  
  69.   local_header_length : constant := 30; 
  70.  
  71.   procedure Read_and_check (stream :     Zipstream_Class; 
  72.                             header : out Local_File_Header); 
  73.  
  74.   bad_local_header : exception; 
  75.  
  76.   procedure Write (stream : Zipstream_Class; 
  77.                    header : Local_File_Header); 
  78.  
  79.   ------------------------------------------------------- 
  80.   -- PKZIP file header, as in central directory - PK12 -- 
  81.   ------------------------------------------------------- 
  82.   -- NB : a central header contains a local header in the middle 
  83.  
  84.   type Central_File_Header is record 
  85.     -- PK12                                   --  1 .. 4 
  86.     made_by_version      : Unsigned_16;       --  5 .. 6 
  87.     short_info           : Local_File_Header; --  7 .. 32 
  88.     comment_length       : Unsigned_16;       -- 33 .. 34 
  89.     disk_number_start    : Unsigned_16; 
  90.     internal_attributes  : Unsigned_16; -- internal properties of data 
  91.     external_attributes  : Unsigned_32; -- 1st byte if MS - DOS : see below 
  92.     local_header_offset  : Unsigned_32; 
  93.   end record; 
  94.  
  95.   -- MS - DOS external attributes: 
  96.   -- 
  97.   --   Bit 0     Read - Only 
  98.   --   Bit 1     Hidden 
  99.   --   Bit 2     System 
  100.   --   Bit 3     Volume Label 
  101.   --   Bit 4     Directory 
  102.   --   Bit 5     Archive 
  103.  
  104.   central_header_length : constant := 46; 
  105.  
  106.   procedure Read_and_check (stream :     Zipstream_Class; 
  107.                             header : out Central_File_Header); 
  108.  
  109.   bad_central_header : exception; 
  110.  
  111.   procedure Write (stream : Zipstream_Class; 
  112.                    header : Central_File_Header); 
  113.  
  114.   ------------------------------------------- 
  115.   -- PKZIP end - of - central - directory - PK56 -- 
  116.   ------------------------------------------- 
  117.  
  118.   type End_of_Central_Dir is record 
  119.     -- PK56                           --  1 .. 4 
  120.     disknum             : Unsigned_16; --  5 .. 6 
  121.     disknum_with_start  : Unsigned_16; 
  122.     disk_total_entries  : Unsigned_16; 
  123.     total_entries       : Unsigned_16; 
  124.     central_dir_size    : Unsigned_32; 
  125.     central_dir_offset  : Unsigned_32; 
  126.     main_comment_length : Unsigned_16; 
  127.     -- The Zip archive may be appended to another file (for instance an 
  128.     -- executable for self - extracting purposes) of size N. 
  129.     -- Then, all offsets need to be shifted by N. 
  130.     -- N=0 if the Zip archive is on its own. 
  131.     -- The real offset of the end - of - central - dir 
  132.     -- will be N + central_dir_size + central_dir_offset. 
  133.     -- This way, we have an unique chance to determine N when reading the 
  134.     -- end - of - central - dir. N is stored in the field hereafter. 
  135.     offset_shifting     : Unsigned_32; 
  136.   end record; 
  137.  
  138.   end_of_central_dir_length  : constant := 22; 
  139.  
  140.   -- This header needs to be read in special 
  141.   -- ways (see Load) - > access to a buffer 
  142.   procedure Copy_and_check (buffer  :     Byte_Buffer; 
  143.                             the_end : out End_of_Central_Dir); 
  144.  
  145.   procedure Read_and_check (stream  :     Zipstream_Class; 
  146.                             the_end : out End_of_Central_Dir); 
  147.  
  148.   bad_end : exception; 
  149.  
  150.   -- A bit more elaborated : from an open file (not a stream), 
  151.   -- find the End - of - Central - dir and load it; keep the file open. 
  152.   procedure Load (stream  :     Zipstream_Class; 
  153.                   the_end : out End_of_Central_Dir); 
  154.  
  155.   procedure Write (stream   : Zipstream_Class; 
  156.                    the_end  : End_of_Central_Dir); 
  157.  
  158. end Zip.Headers;