zipada_58.0.0_08ab9be1/zip_lib/unzip-streams.ads

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
--   ________  ___   ______       ______      ___
--  /___..._/  |.|   |.___.\     /. __ .\   __|.|   ____
--     /../    |.|   |.____/     |.|__|.|  /....|  __\..\
--   _/../___  |.|   |.|    ===  |..__..| |. = .| | = ..|
--  /_______/  |_|  /__|        /__|  |_|  \__\_|  \__\_|

--  UnZip.Streams
-----------------
--
--  Variant 1: extracts, as an *input* stream, a file which is has been
--             compressed into a Zip archive. The Zip archive itself
--             can be a file, or a more general stream. Subprograms are
--             resembling Ada.Streams.Stream_IO, to facilitate transition.
--
--  Variant 2: extracts to an *output* stream a file which is has been
--             compressed into a Zip archive.
--
--  Stream directions in a nutshell...
--
--                     Zip Archive  |  File-in-archive
--                     -------------|-----------------
--      Variant 1:     Input        |  Input
--      Variant 2:     Input        |  Output
--

--  Legal licensing note:

--  Copyright (c) 1999 .. 2020 Gautier de Montmollin
--  SWITZERLAND

--  Permission is hereby granted, free of charge, to any person obtaining a copy
--  of this software and associated documentation files (the "Software"), to deal
--  in the Software without restriction, including without limitation the rights
--  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--  copies of the Software, and to permit persons to whom the Software is
--  furnished to do so, subject to the following conditions:

--  The above copyright notice and this permission notice shall be included in
--  all copies or substantial portions of the Software.

--  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
--  THE SOFTWARE.

--  NB: this is the MIT License, as found on the site
--  http://www.opensource.org/licenses/mit-license.php

with Zip, Zip_Streams;

with Ada.Streams, Ada.IO_Exceptions;

package UnZip.Streams is

   ----------------------------------------------------------------------------
   --                    ** Variant 1: Input Stream **                       --
   --                                                                        --
   --  Extract a Zip archive entry as an input stream.                       --
   --                                                                        --
   --  The workflow is similar to a "physical" file's:                       --
   --                                                                        --
   --    - Open z: Zipped_File_Type                                          --
   --    - do something with Stream(z), usually: read the data               --
   --    - Close z                                                           --
   --                                                                        --
   --  NB: the whole entry is unpacked into memory at Open, so it uses       --
   --      the uncompressed amount as work memory between Open and Close.    --
   ----------------------------------------------------------------------------

   type Zipped_File_Type is private;

   type Count is new Zip_Streams.ZS_Size_Type;

   --  Opens an input stream for the compressed file named Name stored
   --  in the archive file named Archive_Name. The function Stream(..)
   --  then gives access to the opened stream.

   --  Version: Zip as a file.
   procedure Open
     (File             : in out Zipped_File_Type; -- File-in-archive handle
      Archive_Name     : in String;               -- Name of archive file
      Name             : in String;               -- Name of zipped entry
      Password         : in String  := "";        -- Decryption password
      Case_sensitive   : in Boolean := False;
      Ignore_Directory : in Boolean := False      -- True: will open Name in first directory found
     );

   --  Version: Zip as a stream.
   procedure Open
     (File             : in out Zipped_File_Type; -- File-in-archive handle
      Archive_Stream   : in out Zip_Streams.Root_Zipstream_Type'Class; -- Archive's stream
      Name             : in String;               -- Name of zipped entry
      Password         : in String  := "";        -- Decryption password
      Case_sensitive   : in Boolean := False;
      Ignore_Directory : in Boolean := False      -- True: will open Name in first directory found
     );

   --  Same as above, but uses a the pre-loaded contents of the archive's
   --  Central Directory; hence Archive_Info is passed instead of
   --  Archive_Name or Archive_Stream.
   --  You need to call Zip.Load( Archive_Info... ) prior to opening the
   --  compressed file.

   --  Version: Zip as Zip_info.
   procedure Open
     (File             : in out Zipped_File_Type; -- File-in-archive handle
      Archive_Info     : in Zip.Zip_info;         -- Archive's Zip_info
      Name             : in String;               -- Name of zipped entry
      Password         : in String  := "";        -- Decryption password
      Ignore_Directory : in Boolean := False      -- True: will open Name in first directory found
     );

   procedure Close (File : in out Zipped_File_Type);

   function Name (File : in Zipped_File_Type) return String;

   function Is_Open     (File : in Zipped_File_Type) return Boolean;
   function End_Of_File (File : in Zipped_File_Type) return Boolean;

   type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;

   ------------------------------------------------------------------------
   -- The function Stream gives access to the uncompressed data as input --
   ------------------------------------------------------------------------
   function Stream (File : Zipped_File_Type) return Stream_Access;

   function Size (File : in Zipped_File_Type) return Count;

   Use_Error    : exception renames Ada.IO_Exceptions.Use_Error;
   End_Error    : exception renames Ada.IO_Exceptions.End_Error;

   ------------------------------------------------------------------
   --               ** Variant 2: Output Stream **                 --
   --                                                              --
   --  Extract a Zip archive entry to an available output stream.  --
   --                                                              --
   --  NB: the memory footprint is limited to the decompression    --
   --      structures and buffering, so the outward stream can be  --
   --      an interesting alternative to the inward, albeit less   --
   --      comfortable.                                            --
   --                                                              --
   ------------------------------------------------------------------

   procedure Extract (
     Destination      : in out Ada.Streams.Root_Stream_Type'Class;
     Archive_Info     : in Zip.Zip_info;         -- Archive's Zip_info
     Entry_Name       : in String;               -- Name of zipped entry
     Password         : in String  := "";        -- Decryption password
     Ignore_Directory : in Boolean := False      -- True: will open Name in first directory found
   );

private

   type UZS_state is (
      uninitialized,
      data_uncompressed, -- In that model, all data is unzipped in one
                         --   time, into memory. If you have a smarter
                         --   idea (small buffer with tasking, write me!)
      end_of_zip         -- We have reached the end, not yet closed
     );

   type p_String is access String;

   type UnZip_Stream_Type is new Ada.Streams.Root_Stream_Type with record
      state        : UZS_state := uninitialized;
      archive_info : Zip.Zip_info; -- archive info (.zip file, directory)
      file_name    : p_String; -- name of zipped file to unzip from archive
      uncompressed : p_Stream_Element_Array; -- whole uncompressed data
      index        : Ada.Streams.Stream_Element_Offset;
   end record;

   overriding procedure Read
     (Self   : in out UnZip_Stream_Type;
      Item   :    out Ada.Streams.Stream_Element_Array;
      Last   :    out Ada.Streams.Stream_Element_Offset);

   overriding procedure Write
     (Self   : in out UnZip_Stream_Type;
      Item   : in     Ada.Streams.Stream_Element_Array);

   type Zipped_File_Type is access UnZip_Stream_Type;

end UnZip.Streams;