From a8e04943bf22372cd5ae7a1f3880bb4b3559e200 Mon Sep 17 00:00:00 2001 From: Guido Draheim Date: Sun, 9 May 2004 00:24:35 +0000 Subject: [PATCH] documenting zzipfseeko and zzipmmapped libraries () --- ChangeLog | 3 + docs/Makefile.am | 16 ++-- docs/Makefile.in | 15 ++-- docs/body.htm | 6 ++ docs/fseeko.htm | 187 ++++++++++++++++++++++++++++++++++++++++ docs/mmapped.htm | 219 +++++++++++++++++++++++++++++++++++++++++++++++ zziplib.spec | 2 +- 7 files changed, 433 insertions(+), 15 deletions(-) create mode 100644 docs/fseeko.htm create mode 100644 docs/mmapped.htm diff --git a/ChangeLog b/ChangeLog index 62f18f4..d5f2285 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2004-05-09 + * documenting zzipmmapped and zzipfseeko parser libraries + 2004-05-08 * remove bogus zzip_file_open_ext_io from zzip.h * change to use mksite.sh for documentation builds diff --git a/docs/Makefile.am b/docs/Makefile.am index b49514d..5c7608f 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -2,24 +2,26 @@ AUTOMAKE_OPTIONS = 1.4 foreign AUTOTOOL_VERSION=autoconf-2.52 automake-1.5 libtool-1.4.2 doc_FILES = README.MSVC6 README.SDL COPYING.MPL COPYING.LIB COPYING.ZLIB \ - zziplib.html + zziplib.html htm_FILES = zzip-index.htm zzip-zip.htm zzip-file.htm zzip-sdl-rwops.htm \ zzip-extio.htm zzip-xor.htm zzip-crypt.htm \ zzip-api.htm zzip-basics.htm zzip-extras.htm zzip-parse.htm \ - 64on32.htm future.htm configs.htm sfx-make.htm \ - history.htm referentials.htm copying.htm manpages.ar + 64on32.htm future.htm fseeko.htm mmapped.htm \ + configs.htm sfx-make.htm \ + history.htm referentials.htm copying.htm SDL = @top_srcdir@/SDL SDL_RWOPS = $(SDL)/SDL_rwops_zzcat.c \ $(SDL)/SDL_rwops_zzip.c $(SDL)/SDL_rwops_zzip.h changelog = @top_srcdir@/ChangeLog EXTRA_DIST = make-doc.py $(doc_FILES) $(htm_FILES) $(SDL_RWOPS) \ - make-doc.pl make-dbk.pl mksite.sh site.htm + make-doc.pl make-dbk.pl mksite.sh body.htm \ + manpages.ar CLEANFILES = *.pc *.omf DISTCLEANFILES = zziplib.spec manpages.ar htmpages.ar *.html *.xml html_FILES = $(htm_FILES:.htm=.html) \ - $(htm_FILES:.htm=.print.html) + $(htm_FILES:.htm=.print.html) \ site.html site.print.html default : doc @@ -66,7 +68,7 @@ DOCEXAMPLES = $(bins)/zzdir.c $(bins)/zzcat.c \ $(bins)/zzxordir.c $(bins)/zzxorcat.c \ $(bins)/zzxorcopy.c $(SDL_RWOPS) -install-docu: $(doc_FILES) site.html $(PACKAGE)-doc.omf +install-docu: $(doc_FILES) $(man_FILES) site.html $(PACKAGE)-doc.omf $(mkinstalldirs) $(DESTDIR)$(pkgdocdir) for i in $(html_FILES) ; do cat $$i \ | sed -e 's:--START-->:-- :' -e 's::-- :' -e 's: @@ -36,6 +40,8 @@
=Parsing ZIPs
- 64on32 extras
- Next To Come +
<> fseeko +<> mmapped
- Config Helpers
- Making a zip/exe
=Hints And Links diff --git a/docs/fseeko.htm b/docs/fseeko.htm new file mode 100644 index 0000000..c42e053 --- /dev/null +++ b/docs/fseeko.htm @@ -0,0 +1,187 @@ +

zzip/fseeko

zip access for stdio handle + +
+ 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. +
+ +

stdio disk handle

+ +

+ Other than with the mmapped alternative + interface there is no need to build special handle for the zip + disk file. The normal stdio file handle (of type FILE) + serves as the disk access representation. You can open that stdio file + handle any way you want. Note however that the zzipfseeko + routines modify the access state of that file handle, especially the + read position. +

+ +

+ To get access to a zipped file, you need a zip archive entry known + under the type ZZIP_ENTRY. This is again modelled after + the DIR_ENTRY type in being a representation of a file + name inside the zip central directory. To get a fresh zzip entry, use + zzip_entry_findfirst, to get the next use + zzip_entry_findnext, and do not forget to free the + resource with zzip_entry_free. +

+
+   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);
+
+

+ 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 strdup the entry name as a normal C string: +

+
+  #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);
+      }
+  }
+
+ +

find a zipped file

+ +

+ The central directory walk can be used to find any file in the + zip archive. The zzipfseeko 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 ZZIP_ENTRY for later calls on + that handle type. Do not forget to zzip_entry_free + the handle unless the handle is consumed by a routine, e.g. + zzip_entry_findnext to hit the end of directory. +

+
+  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);
+
+

+ 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 + zzip_entry_findnext but actually leaping forward. The + compare function can be used for alternate match behavior: the default + of strcmp might be changed to strncmp for + a caseless match. The "flags" of the second call are forwarded to the + posix fnmatch which we use as the default function. +

+

+ If you do know a specific filename then you can just use + zzip_entry_findfile and supply the return value to + zzip_entry_fopen 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 zzip_entry_free + as it is included in a later zzip_entry_fclose. +

+
+  #include <zzip/fseeko.h>
+
+       /* zzipfseeko already exports this convenience function: */
+  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;
+  }
+
+ +

reading bytes

+ +

+ 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 + fopen(), fread() and fclose(). + These work on an active file descriptor of type ZZIP_ENTRY_FILE. + Note that this zzip_entry_fopen() uses ZZIP_ENTRY + argument as returned by the findfile api. To open a new reader handle from + a disk archive and file name you can use the zzip_entry_ffile() + convenience call. +

+ +
+   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);
+
+ +

+ In all of the examples you need to remember that you provide a single + stdio FILE 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 FILE. +

+ +

ZZIP_ENTRY inspection

+ +

+ The ZZIP_ENTRY_FILE is a special file descriptor handle + of the zzipfseeko library - but the ZZIP_ENTRY + is not so special. It is actually a bytewise copy of the data inside the + zip disk archive (plus some internal hints appended). While + zzip/fseeko.h will not reveal the structure on its own, + you can include zzip/format.h to get access to the actual + structure content of a ZZIP_ENTRY by (up)casting it to +
    struct zzip_disk_entry. +

+ +

+ In reality however it is not a good idea to actually read the bytes + in the zzip_disk_entry 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 zzip/fetch.h. These will take + care to convert any struct data member to the host native format. +

+
+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);
+
diff --git a/docs/mmapped.htm b/docs/mmapped.htm new file mode 100644 index 0000000..8c8be83 --- /dev/null +++ b/docs/mmapped.htm @@ -0,0 +1,219 @@ +

zzip/mmapped

zip access for mmapped views + +
+ These routines are fully independent from the traditional zzip + implementation. They assume a readonly mmapped sharedmem block + representing a complete zip file. The functions show how to + parse the structure, find files and return a decoded bytestream. +
+ +

zzip disk handle

+ +

+ Other than with the fseeko alternative + interface there is no need to have an actual disk handle to the + zip archive. Instead you can use a bytewise copy of a file or + even use a mmapped view of a file. This is generally the fastest + way to get to the data contained in a zipped file. All it requires + is enough of virtual memory space but a desktop computer with a + a modern operating system will easily take care of that. +

+ +

+ The zzipmmapped library provides a number of calls to create a + disk handle representing a zip archive in virtual memory. Per + default we use the sys/mmap.h (or MappedView) functionality + of the operating system. The zzip_disk_open will + open a system file descriptor and try to zzip_disk_mmap + the complete zip content. When finished with the zip archive + call zzip_disk_close to release the mapped view + and all management data. +

+ +
+  ZZIP_DISK*  zzip_disk_open(char* filename);
+  int         zzip_disk_close(ZZIP_DISK* disk);
+
+  ZZIP_DISK*  zzip_disk_new(void);
+  ZZIP_DISK*  zzip_disk_mmap(int fd);
+  int         zzip_disk_munmap(ZZIP_DISK* disk);
+  int         zzip_disk_init(ZZIP_DISK* disk, 
+                            char* buffer, zzip_size_t buflen);
+
+ +

reading the central directory

+ +

+ To get access to a zipped file, you need a pointer to an entry in the + mmapped zip disk known under the type ZZIP_DISK_ENTRY. + This is again modelled after the DIR_ENTRY type in being + a representation of a file name inside the zip central directory. To + get an initial zzip disk entry pointer, use zzip_disk_findfirst, + to move the pointer to the next entry use zzip_disk_findnext. +

+
+   extern ZZIP_ENTRY* zzip_disk_findfirst(FILE* disk);
+   extern ZZIP_ENTRY* zzip_disk_findnext(ZZIP_ENTRY*  entry);
+
+

+ These two 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 strdup the entry name as a normal C string: +

+
+  #include <zzip/mmapped.h>
+  void _zzip_dir(char* filename)
+  {
+      ZZIP_DISK* disk = zzip_disk_open (filename);
+      if (! disk) return disk;
+      for (ZZIP_DISK_ENTRY* entry = zzip_disk_findfirst (disk);
+           entry ; entry = zzip_disk_findnext (entry)) {
+          char* name = zzip_disk_entry_strdup_name (entry);
+          puts (name); free (name);
+      }
+  }
+
+ +

find a zipped file

+ +

+ The central directory walk can be used to find any file in the + zip archive. The zzipfseeko 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 returned ZZIP_DISK_ENTRY pointer for later calls + that type. There is no need to free this pointer as it is really + a pointer into the mmapped area of the ZZIP_DISK. + But do not forget to free that one via zzip_disk_close. +

+
+  ZZIP_DISK_ENTRY* zzip_disk_findfile(ZZIP_DISK* disk, char* filename, 
+                                      ZZIP_DISK_ENTRY* after, 
+                                      zzip_strcmp_fn_t compare);
+
+  ZZIP_DISK_ENTRY* zzip_disk_findmatch(ZZIP_DISK* disk, char* filespec, 
+                                       ZZIP_ENTRY* after,
+                                       zzip_fnmatch_fn_t compare, int flags);
+
+

+ In general only the first two arguments are non-null pointing to the + zip disk handle and the file name to look for. The "after" argument + is an old value and allows you to walk the zip directory similar to + zzip_disk_entry_findnext but actually leaping forward. The + compare function can be used for alternate match behavior: the default + of strcmp might be changed to strncmp for + a caseless match. The "flags" of the second call are forwarded to the + posix fnmatch which we use as the default function. +

+

+ If you do know a specific zzipped filename then you can just use + zzip_disk_entry_findfile and supply the return value to + zzip_disk_entry_fopen. There is a convenience function + zzip_disk_fopen that will do just that and therefore + only requires a disk handle and a filename to find-n-open. +

+
+  #include <zzip/mmapped.h>
+
+  int _zzip_read(ZZIP_DISK* disk, char* filename, void* buffer, int bytes)
+  {
+      ZZIP_DISK_FILE* file = zzip_disk_fopen (disk, filename);
+      if (! file) return -1;
+      int bytes = zzip_disk_fread (buffer, 1, bytes, file);
+      zzip_disk_fclose (file);
+      return bytes;
+  }
+
+ +

reading bytes

+ +

+ The example has shown already how to read some bytes off the head of + a zipped file. In general the zzipmmapped api is used to replace a few + system file routines that access a file. For that purpose we provide three + functions that look very similar to the stdio functions of + fopen(), fread() and fclose(). + These work on an active file descriptor of type ZZIP_DISK_FILE. +

+ +
+   ZZIP_DISK_FILE* zzip_disk_entry_fopen  (ZZIP_DISK* disk, 
+                                           ZZIP_DISK_ENTRY* entry);
+   ZZIP_DISK_FILE* zzip_disk_fopen  (ZZIP_DISK* disk, char* filename);
+   zzip_size_t     zzip_disk_fread  (void* ptr, 
+                                     zzip_size_t sized, zzip_size_t nmemb,
+                                     ZZIP_DISK_FILE* file);
+   int             zzip_disk_fclose (ZZIP_DISK_FILE* file);
+   int             zzip_disk_feof   (ZZIP_DISK_FILE* file);
+
+ +

+ In all of the examples you need to remember that you provide a single + ZZIP_DISK descriptor for a memory block 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 FILE. +

+ +

ZZIP_DISK_ENTRY inspection

+ +

+ The ZZIP_DISK_FILE is a special file descriptor handle + of the zzipmmapped library - but the + ZZIP_DISK_ENTRY is not so special. It is actually a pointer + directly into the zip central directory managed by ZZIP_DISK. + While zzip/mmapped.h will not reveal the structure on its own, + you can include zzip/format.h to get access to the actual + structure content of a ZZIP_DISK_ENTRY by its definition +
    struct zzip_disk_entry. +

+ +

+ In reality however it is not a good idea to actually read the bytes + in the zzip_disk_entry 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 zzip/fetch.h. These will take + care to convert any struct data member to the host native format. +

+
+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);
+
+ +

+ Additionally the zzipmmapped library has two additional + functions that can convert a mmapped disk entry to (a) the local + file header of a compressed file and (b) the start of the data area + of the compressed file. These are used internally upon opening of + a disk entry but they may be useful too for direct inspection of the + zip data area in special applications. +

+
+  char*  zzip_disk_entry_to_data(ZZIP_DISK* disk, 
+                                 struct zzip_disk_entry* entry);
+  struct zzip_file_header*  
+         zzip_disk_entry_to_file_header(ZZIP_DISK* disk, 
+                                 struct zzip_disk_entry* entry);
+
+ diff --git a/zziplib.spec b/zziplib.spec index 1285dd8..9bf4ca9 100644 --- a/zziplib.spec +++ b/zziplib.spec @@ -1,7 +1,7 @@ %define lib lib010 Summary: ZZipLib - libZ-based ZIP-access Library Name: zziplib -Version: 0.13.35 +Version: 0.13.36 Release: 1mdk Serial: 1 Copyright: LGPL -- 2.40.0