]> granicus.if.org Git - zziplib/blob - docs/mmapped.htm
autoreconf 2.63
[zziplib] / docs / mmapped.htm
1 <section> <date> 2005 </date>
2 <H2> zzip/mmapped </H2> zip access for mmapped views
3
4 <BLOCKQUOTE>
5   These routines are fully independent from the traditional zzip
6   implementation. They assume a readonly mmapped sharedmem block
7   representing a complete zip file. The functions show how to 
8   parse the structure, find files and return a decoded bytestream.
9 </BLOCKQUOTE>
10
11 <section>
12 <H3> zzip disk handle </H3>
13
14 <P>
15   Other than with the <a href="fseeko.html">fseeko</a> alternative
16   interface there is no need to have an actual disk handle to the
17   zip archive. Instead you can use a bytewise copy of a file or
18   even use a mmapped view of a file. This is generally the fastest
19   way to get to the data contained in a zipped file. All it requires
20   is enough of virtual memory space but a desktop computer with a
21   a modern operating system will easily take care of that.
22 </P>
23
24 <P>
25   The zzipmmapped library provides a number of calls to create a
26   disk handle representing a zip archive in virtual memory. Per
27   default we use the sys/mmap.h (or MappedView) functionality
28   of the operating system. The <code>zzip_disk_open</code> will
29   open a system file descriptor and try to <code>zzip_disk_mmap</code>
30   the complete zip content. When finished with the zip archive
31   call <code>zzip_disk_close</code> to release the mapped view
32   and all management data.
33 </P>
34
35 <PRE>
36   ZZIP_DISK*  zzip_disk_open(char* filename);
37   int         zzip_disk_close(ZZIP_DISK* disk);
38
39   ZZIP_DISK*  zzip_disk_new(void);
40   ZZIP_DISK*  zzip_disk_mmap(int fd);
41   int         zzip_disk_munmap(ZZIP_DISK* disk);
42   int         zzip_disk_init(ZZIP_DISK* disk, 
43                             char* buffer, zzip_size_t buflen);
44 </PRE>
45
46 </section><section>
47 <H3> reading the central directory </H3>
48
49 <P>
50   To get access to a zipped file, you need a pointer to an entry in the
51   mmapped zip disk known  under the type <code>ZZIP_DISK_ENTRY</code>. 
52   This is again modelled after the <code>DIR_ENTRY</code> type in being 
53   a representation of a file name inside the zip central directory. To 
54   get an initial zzip disk entry pointer, use <code>zzip_disk_findfirst</code>,
55   to move the pointer to the next entry use <code>zzip_disk_findnext</code>.
56 </P>
57 <PRE>
58    extern ZZIP_ENTRY* zzip_disk_findfirst(FILE* disk);
59    extern ZZIP_ENTRY* zzip_disk_findnext(ZZIP_ENTRY*  entry);
60 </PRE>
61 <P>
62   These two calls will allow to walk all zip archive members in the
63   order listed in the zip central directory. To actually implement a
64   directory lister ("zzipdir"), you need to get the name string of the
65   zzip entry. This is not just a pointer: the zzip disk entry is not
66   null terminated actually. Therefore we have a helper function that
67   will <code>strdup</code> the entry name as a normal C string:
68 </P>
69 <PRE>
70   #include &lt;zzip/mmapped.h&gt;
71   void _zzip_dir(char* filename)
72   {
73       ZZIP_DISK* disk = zzip_disk_open (filename);
74       if (! disk) return disk;
75       for (ZZIP_DISK_ENTRY* entry = zzip_disk_findfirst (disk);
76            entry ; entry = zzip_disk_findnext (entry)) {
77           char* name = zzip_disk_entry_strdup_name (entry);
78           puts (name); free (name);
79       }
80   }
81 </PRE>
82
83 </section><section>
84 <H3> find a zipped file </H3>
85
86 <P>
87   The central directory walk can be used to find any file in the
88   zip archive. The <code>zzipfseeko</code> library however provides
89   two convenience functions that allow to jump directly to the
90   zip disk entry of a given name or pattern. You are free to use
91   the returned <code>ZZIP_DISK_ENTRY</code> pointer for later calls
92   that type. There is no need to free this pointer as it is really
93   a pointer into the mmapped area of the <code>ZZIP_DISK</code>.
94   But do not forget to free that one via <code>zzip_disk_close</code>.
95 </P>
96 <PRE>
97   ZZIP_DISK_ENTRY* zzip_disk_findfile(ZZIP_DISK* disk, char* filename, 
98                                       ZZIP_DISK_ENTRY* after, 
99                                       zzip_strcmp_fn_t compare);
100
101   ZZIP_DISK_ENTRY* zzip_disk_findmatch(ZZIP_DISK* disk, char* filespec, 
102                                        ZZIP_ENTRY* after,
103                                        zzip_fnmatch_fn_t compare, int flags);
104 </PRE>
105 <P>
106   In general only the first two arguments are non-null pointing to the
107   zip disk handle and the file name to look for. The "after" argument
108   is an old value and allows you to walk the zip directory similar to
109   <code>zzip_disk_entry_findnext</code> but actually leaping forward. The
110   compare function can be used for alternate match behavior: the default
111   of <code>strcmp</code> might be changed to <code>strncmp</code> for
112   a caseless match. The "flags" of the second call are forwarded to the
113   posix <code>fnmatch</code> which we use as the default function.
114 </P>
115 <P>
116   If you do know a specific zzipped filename then you can just use 
117   <code>zzip_disk_entry_findfile</code> and supply the return value to
118   <code>zzip_disk_entry_fopen</code>. There is a convenience function 
119   <code>zzip_disk_fopen</code> that will do just that and therefore
120   only requires a disk handle and a filename to find-n-open.
121 </P>
122 <PRE>
123   #include &lt;zzip/mmapped.h&gt;
124
125   int _zzip_read(ZZIP_DISK* disk, char* filename, void* buffer, int bytes)
126   {
127       ZZIP_DISK_FILE* file = zzip_disk_fopen (disk, filename);
128       if (! file) return -1;
129       int bytes = zzip_disk_fread (buffer, 1, bytes, file);
130       zzip_disk_fclose (file);
131       return bytes;
132   }
133 </PRE>
134
135 </section><section>
136 <H3> reading bytes </H3>
137
138 <P>
139   The example has shown already how to read some bytes off the head of
140   a zipped file. In general the zzipmmapped api is used to replace a few
141   system file routines that access a file. For that purpose we provide three 
142   functions that look very similar to the stdio functions of 
143   <code>fopen()</code>, <code>fread()</code> and <code>fclose()</code>.
144   These work on an active file descriptor of type <code>ZZIP_DISK_FILE</code>.
145 </P>
146
147 <PRE>
148    ZZIP_DISK_FILE* zzip_disk_entry_fopen  (ZZIP_DISK* disk, 
149                                            ZZIP_DISK_ENTRY* entry);
150    ZZIP_DISK_FILE* zzip_disk_fopen  (ZZIP_DISK* disk, char* filename);
151    zzip_size_t     zzip_disk_fread  (void* ptr, 
152                                      zzip_size_t sized, zzip_size_t nmemb,
153                                      ZZIP_DISK_FILE* file);
154    int             zzip_disk_fclose (ZZIP_DISK_FILE* file);
155    int             zzip_disk_feof   (ZZIP_DISK_FILE* file);
156 </PRE>
157
158 <P>
159   In all of the examples you need to remember that you provide a single
160   <code>ZZIP_DISK</code> descriptor for a memory block which is in reality 
161   a virtual filesystem on its own. Per default filenames are matched case
162   sensitive also on win32 systems. The findnext function will walk all
163   files on the zip virtual filesystem table and return a name entry 
164   with the full pathname, i.e. including any directory names to the
165   root of the zip disk <code>FILE</code>.
166 </P>
167
168 </section><section>
169 <H3> ZZIP_DISK_ENTRY inspection </H3>
170
171 <P>
172   The <code>ZZIP_DISK_FILE</code> is a special file descriptor handle 
173   of the <code>zzipmmapped</code> library - but the 
174   <code>ZZIP_DISK_ENTRY</code> is not so special. It is actually a pointer
175   directly into the zip central directory managed by <code>ZZIP_DISK</code>.
176   While <code>zzip/mmapped.h</code> will not reveal the structure on its own, 
177   you can include <code>zzip/format.h</code> to get access to the actual 
178   structure content of a <code>ZZIP_DISK_ENTRY</code> by its definition
179 <br><b><code>&nbsp;&nbsp;&nbsp;&nbsp;struct zzip_disk_entry</code></b>.
180 </P>
181
182 <P>
183   In reality however it is not a good idea to actually read the bytes
184   in the <code>zzip_disk_entry</code> structure unless you seriously know
185   the internals of a zip archive entry. That includes any byteswapping
186   needed on bigendian platforms. Instead you want to take advantage of
187   helper macros defined in <code>zzip/fetch.h</code>. These will take
188   care to convert any struct data member to the host native format.
189 </P>
190 <PRE>
191 extern uint16_t    zzip_disk_entry_get_flags( zzip_disk_entry* entry);
192 extern uint16_t    zzip_disk_entry_get_compr( zzip_disk_entry* entry);
193 extern uint32_t    zzip_disk_entry_get_crc32( zzip_disk_entry* entry);
194
195 extern zzip_size_t zzip_disk_entry_csize( zzip_disk_entry* entry);
196 extern zzip_size_t zzip_disk_entry_usize( zzip_disk_entry* entry);
197 extern zzip_size_t zzip_disk_entry_namlen( zzip_disk_entry* entry);
198 extern zzip_size_t zzip_disk_entry_extras( zzip_disk_entry* entry);
199 extern zzip_size_t zzip_disk_entry_comment( zzip_disk_entry* entry);
200 extern int         zzip_disk_entry_diskstart( zzip_disk_entry* entry);
201 extern int         zzip_disk_entry_filetype( zzip_disk_entry* entry);
202 extern int         zzip_disk_entry_filemode( zzip_disk_entry* entry);
203
204 extern zzip_off_t  zzip_disk_entry_fileoffset( zzip_disk_entry* entry);
205 extern zzip_size_t zzip_disk_entry_sizeof_tail( zzip_disk_entry* entry);
206 extern zzip_size_t zzip_disk_entry_sizeto_end( zzip_disk_entry* entry);
207 extern char*       zzip_disk_entry_skipto_end( zzip_disk_entry* entry);
208 </PRE>
209
210 <P>
211   Additionally the <code>zzipmmapped</code> library has two additional
212   functions that can convert a mmapped disk entry to (a) the local
213   file header of a compressed file and (b) the start of the data area
214   of the compressed file. These are used internally upon opening of
215   a disk entry but they may be useful too for direct inspection of the
216   zip data area in special applications.
217 </P>
218 <PRE>
219   char*  zzip_disk_entry_to_data(ZZIP_DISK* disk, 
220                                  struct zzip_disk_entry* entry);
221   struct zzip_file_header*  
222          zzip_disk_entry_to_file_header(ZZIP_DISK* disk, 
223                                  struct zzip_disk_entry* entry);
224 </PRE>
225
226 </section></section>