diff options
Diffstat (limited to 'Build/source/libs/zziplib/zziplib-src/docs/fseeko.htm')
-rw-r--r-- | Build/source/libs/zziplib/zziplib-src/docs/fseeko.htm | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/Build/source/libs/zziplib/zziplib-src/docs/fseeko.htm b/Build/source/libs/zziplib/zziplib-src/docs/fseeko.htm new file mode 100644 index 00000000000..89c3195e36d --- /dev/null +++ b/Build/source/libs/zziplib/zziplib-src/docs/fseeko.htm @@ -0,0 +1,193 @@ +<section> <date> 2005 </date> +<H2> zzip/fseeko </H2> zip access for stdio handle + +<BLOCKQUOTE> + These routines are fully independent from the traditional zzip + implementation. They assume a readonly seekable stdio handle + representing a complete zip file. The functions show how to + parse the structure, find files and return a decoded bytestream. +</BLOCKQUOTE> + +<section> +<H3> stdio disk handle </H3> + +<P> + Other than with the <a href="mmapped.html">mmapped</a> alternative + interface there is no need to build special handle for the zip + disk file. The normal stdio file handle (of type <b><code>FILE</code></b>) + serves as the disk access representation. You can open that stdio file + handle any way you want. Note however that the <code>zzipfseeko</code> + routines modify the access state of that file handle, especially the + read position. +</P> + +<P> + To get access to a zipped file, you need a zip archive entry known + under the type <code>ZZIP_ENTRY</code>. This is again modelled after + the <code>DIR_ENTRY</code> type in being a representation of a file + name inside the zip central directory. To get a fresh zzip entry, use + <code>zzip_entry_findfirst</code>, to get the next use + <code>zzip_entry_findnext</code>, and do not forget to free the + resource with <code>zzip_entry_free</code>. +</P> +<PRE> + extern ZZIP_ENTRY* zzip_entry_findfirst(FILE* disk); + extern ZZIP_ENTRY* zzip_entry_findnext(ZZIP_ENTRY* entry); + extern int zzip_entry_free(ZZIP_ENTRY* entry); +</PRE> +<P> + These three calls will allow to walk all zip archive members in the + order listed in the zip central directory. To actually implement a + directory lister ("zzipdir"), you need to get the name string of the + zzip entry. This is not just a pointer: the zzip disk entry is not + null terminated actually. Therefore we have a helper function that + will <code>strdup</code> the entry name as a normal C string: +</P> +<PRE> + #include <zzip/fseeko.h> + void _zzip_dir(FILE* disk) + { + for (ZZIP_ENTRY* entry = zzip_findfirst (disk); + entry ; entry = zzip_findnext (entry)) { + char* name = zzip_entry_strdup_name (entry); + puts (name); free (name); + } + } +</PRE> + +</section><section> +<H3> find a zipped file </H3> + +<P> + The central directory walk can be used to find any file in the + zip archive. The <code>zzipfseeko</code> library however provides + two convenience functions that allow to jump directly to the + zip disk entry of a given name or pattern. You are free to use + the newly allocated <code>ZZIP_ENTRY</code> for later calls on + that handle type. Do not forget to <code>zzip_entry_free</code> + the handle unless the handle is consumed by a routine, e.g. + <code>zzip_entry_findnext</code> to hit the end of directory. +</P> +<PRE> + extern ZZIP_ENTRY* zzip_entry_findfile(FILE* disk, char* filename, + ZZIP_ENTRY* _zzip_restrict entry, + zzip_strcmp_fn_t compare); + + extern ZZIP_ENTRY* zzip_entry_findmatch(FILE* disk, char* filespec, + ZZIP_ENTRY* _zzip_restrict entry, + zzip_fnmatch_fn_t compare, int flags); +</PRE> +<P> + In general only the first two arguments are non-null pointing to the + stdio disk handle and the file name to look for. The "entry" argument + is an old value and allows you to walk the zip directory similar to + <code>zzip_entry_findnext</code> but actually leaping forward. The + compare function can be used for alternate match behavior: the default + of <code>strcmp</code> might be changed to <code>strncmp</code> for + a caseless match. The "flags" of the second call are forwarded to the + posix <code>fnmatch</code> which we use as the default function. +</P> +<P> + If you do know a specific filename then you can just use + <code>zzip_entry_findfile</code> and supply the return value to + <code>zzip_entry_fopen</code> with the second argument set to "1" + to tell the function to actually consume whichever entry was given. + That allows you to skip an explicit <code>zzip_entry_free</code> + as it is included in a later <code>zzip_entry_fclose</code>. +</P> +<PRE> + #include <zzip/fseeko.h> +<small> + /* zzipfseeko already exports this convenience function: */</small> + ZZIP_ENTRY_FILE* zzip_entry_ffile(FILE* disk, char* filename) { + return zzip_entry_fopen (zzip_entry_findfile (filename, 0, 0), 1); + } + + int _zzip_read(FILE* disk, char* filename, void* buffer, int bytes) + { + ZZIP_ENTRY_FILE* file = zzip_entry_ffile (disk, filename); + if (! file) return -1; + int bytes = zzip_entry_fread (buffer, 1, bytes, file); + zzip_entry_fclose (file); + return bytes; + } +</PRE> + +</section><section> +<H3> reading bytes </H3> + +<P> + The example has shown already how to read some bytes off the head of + a zipped file. In general the zzipfseeko api is used to replace a few + stdio routines that access a file. For that purpose we provide three + functions that look very similar to the stdio functions of + <code>fopen()</code>, <code>fread()</code> and <code>fclose()</code>. + These work on an active file descriptor of type <code>ZZIP_ENTRY_FILE</code>. + Note that this <code>zzip_entry_fopen()</code> uses <code>ZZIP_ENTRY</code> + argument as returned by the findfile api. To open a new reader handle from + a disk archive and file name you can use the <code>zzip_entry_ffile()</code> + convenience call. +</P> + +<PRE> + ZZIP_ENTRY_FILE* zzip_entry_ffile (FILE* disk, char* filename); + ZZIP_ENTRY_FILE* zzip_entry_fopen (ZZIP_ENTRY* entry, int takeover); + zzip_size_t zzip_entry_fread (void* ptr, + zzip_size_t sized, zzip_size_t nmemb, + ZZIP_ENTRY_FILE* file); + int zzip_entry_fclose (ZZIP_ENTRY_FILE* file); + int zzip_entry_feof (ZZIP_ENTRY_FILE* file); +</PRE> + +<P> + In all of the examples you need to remember that you provide a single + stdio <code>FILE</code> descriptor which is in reality a virtual + filesystem on its own. Per default filenames are matched case + sensitive also on win32 systems. The findnext function will walk all + files on the zip virtual filesystem table and return a name entry + with the full pathname, i.e. including any directory names to the + root of the zip disk <code>FILE</code>. +</P> + +</section><section> +<H3> ZZIP_ENTRY inspection </H3> + +<P> + The <code>ZZIP_ENTRY_FILE</code> is a special file descriptor handle + of the <code>zzipfseeko</code> library - but the <code>ZZIP_ENTRY</code> + is not so special. It is actually a bytewise copy of the data inside the + zip disk archive (plus some internal hints appended). While + <code>zzip/fseeko.h</code> will not reveal the structure on its own, + you can include <code>zzip/format.h</code> to get access to the actual + structure content of a <code>ZZIP_ENTRY</code> by (up)casting it to +<br><b><code> struct zzip_disk_entry</code></b>. +</P> + +<P> + In reality however it is not a good idea to actually read the bytes + in the <code>zzip_disk_entry</code> structure unless you seriously know + the internals of a zip archive entry. That includes any byteswapping + needed on bigendian platforms. Instead you want to take advantage of + helper macros defined in <code>zzip/fetch.h</code>. These will take + care to convert any struct data member to the host native format. +</P> +<PRE> +extern uint16_t zzip_disk_entry_get_flags( zzip_disk_entry* entry); +extern uint16_t zzip_disk_entry_get_compr( zzip_disk_entry* entry); +extern uint32_t zzip_disk_entry_get_crc32( zzip_disk_entry* entry); + +extern zzip_size_t zzip_disk_entry_csize( zzip_disk_entry* entry); +extern zzip_size_t zzip_disk_entry_usize( zzip_disk_entry* entry); +extern zzip_size_t zzip_disk_entry_namlen( zzip_disk_entry* entry); +extern zzip_size_t zzip_disk_entry_extras( zzip_disk_entry* entry); +extern zzip_size_t zzip_disk_entry_comment( zzip_disk_entry* entry); +extern int zzip_disk_entry_diskstart( zzip_disk_entry* entry); +extern int zzip_disk_entry_filetype( zzip_disk_entry* entry); +extern int zzip_disk_entry_filemode( zzip_disk_entry* entry); + +extern zzip_off_t zzip_disk_entry_fileoffset( zzip_disk_entry* entry); +extern zzip_size_t zzip_disk_entry_sizeof_tail( zzip_disk_entry* entry); +extern zzip_size_t zzip_disk_entry_sizeto_end( zzip_disk_entry* entry); +extern char* zzip_disk_entry_skipto_end( zzip_disk_entry* entry); +</PRE> +</section></section> |