]> granicus.if.org Git - zziplib/commitdiff
This commit was generated by cvs2svn to compensate for changes in r57, which
authorGuido Draheim <guidod@gmx.de>
Fri, 14 Feb 2003 16:00:59 +0000 (16:00 +0000)
committerGuido Draheim <guidod@gmx.de>
Fri, 14 Feb 2003 16:00:59 +0000 (16:00 +0000)
included commits to RCS files with non-trunk default branches.

docs/configs.htm [new file with mode: 0644]
docs/zzip-api.htm [new file with mode: 0644]
docs/zzip-extio.htm [new file with mode: 0644]
docs/zzip-sdl-rwops.htm [new file with mode: 0644]

diff --git a/docs/configs.htm b/docs/configs.htm
new file mode 100644 (file)
index 0000000..62094c5
--- /dev/null
@@ -0,0 +1,155 @@
+<h2> Configuration </h2>                    of other projects using zziplib
+
+<!--border--> <date> February 2003 </date>
+
+<P>
+  If using the zziplib with other project then you can use a number
+  of possibility to configure and link. The zziplib had been usually
+  included within the projects that made use of it - some did even
+  pick up the advantage to be allowed to staticlink in a limited
+  set of conditions. Recently however, the zziplib is shipped as a
+  standard library of various linux/freebsd distros - mostly for
+  the usage by the php-zip module. This allows third party software
+  makers to link to the preinstalled library in the system and
+  consequently reduce the memory consumption - even more than now
+  with the zziplib being a lightweight anyway (the i386 .so is 
+  usually less than 20k)
+</P>
+
+<h3> pkg-config --libs </h3>
+
+<P>
+  Within modern software development, one should be advised to use
+  pkg-config as soon as it is available. The pkg-config helper can
+  handle a lot of problems that can usually come up with linking
+  to third party libraries in case that those link again dynamically
+  with other libraries themselves. It does correctly order the
+  list of "libs", it can throw away duplicate "-L" hints, and same
+  for cflags "-I" hints, plus it will throw away some sys-includes
+  that gcc3.2 will warn about with a false positive.
+</P>
+<P>
+  There is a number of pkg-config targets installed in the system
+  but the one you want to use is <b>pkg-config zziplib</b>. 
+  Therefore, a simple Makefile could read like
+  <pre>
+    PROGRAM = my_prog
+    CFLAGS = -Dhappy `pkg-config zziplib --cflags`
+    LIBS   = -Wl,-E  `pkg-config zziplib --libs`
+
+    my_prog.o : my_prog.c
+       $(CC) $(CFLAGS) $< -o $@
+    my_prog : my_prog.o
+       $(LINK) $< $(LIBS)
+  </pre>
+</P>
+<P>
+   The `pkg-config zziplibs --libs` will usually expand to 
+   something like <code>-lzzip -lz</code> which are the
+   two (!!) libraries that you need to link with - in that
+   order. The zziplib builds on top of the z-lib algorithms
+   for compression of files within the zip-archive. That's
+   the same for other lib-parts of the zziplib project as
+   well, e.g. the sdl-rwops part which does also need to
+   link with the sdl-lib - and that's where the pkg-config
+   infrastructure can be of great help. That's the reason
+   why zziplib installs a few more ".pc" files, you can
+   get a list of them like this:
+   <pre>
+   $ pkg-config --list-all | sort | grep zzip
+   zziplib               zziplib - ZZipLib - libZ-based ZIP-access Library
+   zzip-sdl-config       zzip-sdl-config - SDL Config (for ZZipLib)
+   zzip-sdl-rwops        zzip-sdl-rwops - SDL_rwops for ZZipLib
+   zzipwrap              zzipwrap - Callback Wrappers for ZZipLib
+   zzip-zlib-config      zzip-zlib-config - ZLib Config (for ZZipLib)
+   </pre>
+   The two entries like "zzip-sdl-config" and "zzip-zlib-config"
+   happen to be ".pc" files for the libz.so and libSDL.so that
+   were seen at configure-time of zziplib - you may want to reuse
+   these in your projects as well whenever you need to link to
+   either of zlib or libsdl even in places where there is no direct
+   need for zziplib. It basically looks like:
+   <pre>
+   $ pkg-config zzip-zlib-config --modversion
+   1.1.4
+   $ pkg-config zzip-zlib-config --libs      
+    -lz  
+   </pre>
+</P>
+
+<h3> zzip-config </h3>
+<P>
+   The pkg-config ".pc" files are relativly young in the history of
+   zziplib. A long time before that there was the `zzip-config`
+   script installed in the system. These `*-config` were common
+   before the pkg-config came about, and in fact the pkg-config
+   infrastructure was invented to flatten away the problems of
+   using multiple `*-config` scripts for a project. As long as you
+   do not combine multiple `*-config`s then it should be well okay
+   to use the `zzip-config` directly - it does also kill another
+   dependency on the `pkg-config` tool to build your project, the
+   zziplib is all that's needed.
+</P>
+<P>
+   In its call-structure the `zzip-config` script uses the same
+   options as `pkg-config`, (well they are historic cousins anyway).
+   and that simply means you can replace each call above like
+   `pkg-config zziplib...` with `zzip-config...`.
+
+  <pre>
+    PROGRAM = my_prog
+    CFLAGS = -Dhappy `zzip-config --cflags`
+    LIBS   = -Wl,-E  `zzip-config --libs`
+
+    my_prog.o : my_prog.c
+       $(CC) $(CFLAGS) $< -o $@
+    my_prog : my_prog.o
+       $(LINK) $< $(LIBS)
+  </pre>
+</P>
+<P>
+   Be informed that the zzip-config script is low-maintained and
+   starting with 2004 it will be replaced with a one-line script 
+   that simply reads `pkg-config zziplib $*`. By that time the
+   rpm/deb packages will also list "pkgconfig" as a dependency
+   on the zziplib-devel/zziplib-dev part.
+</P>
+
+<h3> autoconf macro </h3>
+
+<P>
+  There is currently an autoconf macro installed along into
+  the usual /usr/share/aclocal space for making it easier for
+  you to pick up the configure-time cflags/libs needed to
+  build/link with zziplib. In any way it does look like
+  this:
+  <pre>
+  dnl PKG_CHECK_ZZIPLIB(ZSTUFF, min-version, action-if, action-not)
+  AC_DEFUN([PKG_CHECK_ZZIPLIB],[dnl
+  PKG_CHECK_MODULES([$1], [zziplib $2], [$3], [$4])])
+  </pre>
+</P>
+<P>
+  You are strongly advised to take advantage of the pkgconfig's
+  macro directly - you can find the macro in
+  <code>/usr/share/aclocal/pkg.m4</code> and it allows to
+  combine the flags of a list of library modules that you
+  want to have. If it is only zziplib, than you could simply
+  use this in your configure.ac:
+  <pre>
+  PKG_CHECK_MODULES([ZZIP],[zziplib >= 0.10.75])
+  </pre>
+  which will provide you with two autoconf/automake variables
+  named ZZIP_CFLAGS and ZZIP_LIBS respectivly.
+</P>
+<P>
+  Up to 2004, the macro in zziplib.m4 will be however carry
+  a copy of the pkg.m4 so that you do not need another
+  dependency for your software project. The macro is called
+  like shown above PKG_CHECK_ZZIPLIB and you would call it
+  like
+  <pre>PKG_CHECK_ZZIPLIB([ZZIP],[0.10.75])</pre>
+  which will give you the two autoconf/automake variables
+  as well, ZZIP_CFLAGS and ZZIP_LIBS.
+</P>
+
diff --git a/docs/zzip-api.htm b/docs/zzip-api.htm
new file mode 100644 (file)
index 0000000..a3632e0
--- /dev/null
@@ -0,0 +1,318 @@
+<h2> ZZIP Programmers Interface </h2>   The complete API description.
+
+<!--border--> <date> 20. July 2002 </date>
+
+<h3> Basics </h3>
+
+<P>
+  The naming schem of functions in this library follow a simple rule: 
+  if you see a function with a <code>zzip_</code> prefix followed by 
+  compact name representing otherwise a C library or posix function then 
+  it is a magic wrapper that can automagically handle both real 
+  files/directories or zip-contained files. This includes:
+</P>
+<table cellpadding=10 width=100%><tr><td><table border=1 width=100%>
+  <tr><td width=50%> zzip_opendir   </td><td width=50%> opendir </td></tr>
+  <tr><td width=50%> zzip_readdir   </td><td width=50%> readdir </td></tr>
+  <tr><td width=50%> zzip_closedir  </td><td width=50%> closedir </td></tr>
+  <tr><td width=50%> zzip_rewinddir </td><td width=50%> rewinddir </td></tr>
+  <tr><td width=50%> zzip_telldir   </td><td width=50%> telldir </td></tr>
+  <tr><td width=50%> zzip_seekdir   </td><td width=50%> seekdir </td></tr>
+</table></td></tr></table>
+<P>
+  The ZZIP_DIR handle can wrap both a real directory or a zip-file. 
+  Note that you can not open a virtual directory <em>within</em> a
+  zip-file, the ZZIP_DIR is either a real DIR-handle of a real 
+  directory or the reference of ZIP-file but never a DIR-handle
+  within a ZIP-file - there is no such schema of a SUB-DIR handle
+  implemented in this library. A ZZIP_DIR does actually represent
+  the central directory of a ZIP-file, so that each file entry in 
+  this ZZIP-DIR can possibly have a subpath prepended.
+</P>
+
+<P>
+  This form of magic has historic reasons as originally the 
+  magic wrappers of this library were not meant to wrap a complete
+  subtree of a real file tree but only a single directory being
+  wrapped with into a zip-file and placed instead. Later proposals
+  and patches were coming in to support subtree wrapping by not
+  only making a split between the dir-part and file-part but
+  going recursivly up through all "/"-dirseparators of a filepath
+  given to <code>zzip_open</code> and looking for zip-file there.
+</P>
+
+<P>
+  To open a zip-file unconditionally one should be using their
+  respective methods that would return a ZZIP_DIR handle being
+  the representant memory instance of a ZIP-DIR, the central
+  directory of a zip-file. From that ZZIP-DIR one can open a
+  compressed file entry which will be returned as a ZZIP_FILE
+  pointer.
+</P>
+<table cellpadding=10 width=100%><tr><td><table border=1 width=100%>
+  <tr><td width=50%> zzip_dir_open  </td>
+      <td width=50%> open a zip-file and parse the central directory 
+                                              to a memory shadow</td></tr>
+  <tr><td width=50%> zzip_dir_close  </td>
+      <td width=50%> close a zip-file and free the memory shadow</td></tr>
+  <tr><td width=50%> zzip_dir_fdopen  </td>
+      <td width=50%> aquire the given posix-file and try to parse it 
+                                                  as a zip-file.</td></tr>
+  <tr><td width=50%> zzip_dir_read  </td>
+      <td width=50%> return the next info entry of a zip-file's central
+                 directory - this would include a possible subpath </td></tr>
+</table></td></tr></table>
+
+<P>
+  To unconditionally access a zipped-file (as the counter-part of a 
+  zip-file's directory) you should be using the functions having a
+  <code>zzip_file_</code> prefix which are the methods working on
+  ZZIP_FILE pointers directly and assuming those are references of
+  a zipped file with a ZZIP_DIR. 
+</P>
+<table cellpadding=10 width=100%><tr><td><table border=1 width=100%>
+  <tr><td width=50%> zzip_file_open  </td>
+      <td width=50%> open a file within a zip and prepare a zlib 
+                     compressor for it - note the ZZIP_DIR argument,
+                     multiple ZZIP_FILE's may share the same central
+                     directory shadow.</td></tr>
+  <tr><td width=50%> zzip_file_close  </td>
+      <td width=50%> close the handle of zippedfile
+                     and free zlib compressor of it</td></tr>
+  <tr><td width=50%> zzip_file_read  </td>
+      <td width=50%> decompress the next part of a compressed file
+                     within a zip-file</td></tr>
+</table></td></tr></table>
+<P>
+  From here it is only a short step to the magic wrappers for
+  file-access - when being given a filepath to zzip_open then
+  the filepath is checked first for being possibly a real file
+  (we can often do that by a <code>stat</code> call) and if there is
+  a real file under that name then the returned ZZIP_FILE is
+  nothing more than a wrapper around a file-descriptor of the
+  underlying operating system. Any other calls like zzip_read
+  will see the realfd-flag in the ZZIP_FILE and forward the 
+  execution to the read() function of the underlying operating system.
+</P>
+
+<P>
+  However if that fails then the filepath is cut at last directory
+  separator, i.e. a filepath of "this/test/README" is cut into the
+  dir-part "this/test" and a file-part "README". Then the possible
+  zip-extensions are attached (".zip" and ".ZIP") and we check if
+  there is a real file under that name. If a file "this/test.zip"
+  does exist then it is given to zzip_dir_open which will create
+  a ZZIP_DIR instance of it, and when that was successul (so it
+  was in zip-format) then we call zzip_file_open which will see
+  two arguments - the just opened ZZIP_DIR and the file-part. The
+  resulting ZZIP_FILE has its own copy of a ZZIP_DIR, so if you
+  open multiple files from the same zip-file than you will also
+  have multiple in-memory copies of the zip's central directory
+  whereas otherwise multiple ZZIP_FILE's may share a common
+  ZZIP_DIR when being opened with zzip_file_open directly - the
+  zzip_file_open's first argument is the ZZIP_DIR and the second
+  one the file-part to be looked up within that zip-directory.
+</P>
+
+<table cellpadding=10 width=100%><tr><td><table border=1 width=100%>
+  <tr><td width=50%> zzip_open  </td>
+      <td width=50%> try the file-path as a real-file, and if not
+                     there, look for the existance of ZZIP_DIR by
+                     applying extensions, and open the file 
+                     contained within that one.</td></tr>
+  <tr><td width=50%> zzip_close  </td>
+      <td width=50%> if the ZZIP_FILE wraps a real-file, then call
+                     read(), otherwise call zzip_file_read() </td></tr>
+  <tr><td width=50%> zzip_close  </td>
+      <td width=50%> if the ZZIP_FILE wraps a real-file, then call
+                     close(), otherwise call zzip_file_close() </td></tr>
+</table></td></tr></table>
+
+<P>
+  Up to here we have the original functionality of the zziplib
+  when I (Guido Draheim) created the magic functions around the work from 
+  Tomi Ollila who wrote the routines to read and decompress files from
+  a zip archive - unlike other libraries it was quite readable and
+  intelligible source code (after many changes there is not much
+  left of the original zip08x source code but that's another story).
+  Later however some request and proposals and patches were coming in.
+</P>
+
+<P>
+  Among the first extensions was the recursive zzip_open magic. In
+  the first instance, the library did just do as described above:
+  a file-path of "this/test/README" might be a zip-file known as
+  "this/test.zip" containing a compressed file "README". But if 
+  there is neither a real file "this/test/README" and no real
+  zip-file "this/test.zip" then the call would have failed but
+  know the zzip_open call will recursivly check the parent
+  directories - so it can now find a zip-file "this.zip" which
+  contains a file-part "test/README". 
+</P>
+
+<P>
+  This dissolves the original meaning of a ZZIP_DIR and it has lead 
+  to some confusion later on - you can not create a DIRENT-like handle
+  for "this/test/" being within a "test.zip" file. And actually, I did
+  never see a reason to implement it so far (open "this.zip" and set
+  an initial subpath of "test" and let zzip_readdir skip all entries
+  that do not start with "test/"). This is left for excercie ;-)
+</P>
+
+<h3> Extras </h3>
+
+<P>
+  The next requests circulated around other file-extensions to 
+  automagically look inside filetypes that have zip-format too but 
+  carry other fileextensions - most famous might be the ".PK3"
+  files of ID's Quake game. There have been a number of these
+  requests and in a lot of cases it dawned to me that those guys
+  may have overlooked the zzip_dir_open functions to travel
+  through documents of zipformat under any name - that is that the
+  "magic" was not actually needed but they just wanted to read
+  files in zipformat with the zziplib.
+</P>
+
+<P>
+  Other requests circulated around encryption but I did reject
+  those bluntly, always. Instead there have been always examples
+  for doing some obfuscation around the zip-format so that the
+  stock zip/unzip tools do not recognize them but a game
+  software developer can pack/unpack his AI scripts and bitmaps
+  into such a zipformat-like file.
+</P>
+
+<P>
+  After some dead-end patches (being shipped along with the
+  zziplib as configure-time compile-options - greetings to
+  Lutz Sammer and Andreas Schiffler), the general approach 
+  of _ext_io came up, and finally implemented (greetings go
+  to Mike Nordell). The _open()-calls do now each have a
+  cousin of _open_ext_io() with two/three additional arguments
+  being a set of extensions to loop through our magic testing,
+  a callback-handler plugin-table for obfuscation-means, 
+  and (often) a bit-mask for extra-options - this bitmask even
+  has "PREFERZIP" and "ONLYZIP" options to skip the real-file
+  test magic in those <code>zzip_*open</code> functions.
+</P>
+
+<table cellpadding=10 width=100%><tr><td><table border=1 width=100%>
+  <tr><td width=50%> zzip_open(name,flags) </td>
+      <td width=50%> zzip_open_ext_io(name,flags,mode,ext,io) </td></tr>
+  <tr><td width=50%> zzip_opendir(name) </td>
+      <td width=50%> zzip_opendir_ext_io(name,mode,ext,io) </td></tr>
+  <tr><td width=50%> zzip_dir_open(name,errp) </td>
+      <td width=50%> zzip_dir_open_ext_io(name,errp,ext,io) </td></tr>
+  <tr><td width=50%> zzip_dir_fdopen(fd,errp) </td>
+      <td width=50%> zzip_dir_fdopen_ext_io(fd,errp,ext,io) </td></tr>
+  <tr><td width=50%> zzip_file_open(dir,name,mode) </td>
+      <td width=50%> zzip_file_open_ext_io(dir,name,mode,ext,io) </td></tr>
+</table></td></tr></table>
+
+<P>
+  Oh, and note that the mode,ext,io extras are memorized 
+  in the respecitive ZZIP_DIR handle attached, so each
+  of the other calls like <code>zzip_file_open()</code>
+  and <code>zzip_read()</code> will be using them. There
+  are a few helper routines to help setup a new io-plugin
+  where the init_io will currently just memcopy the
+  default_io entries into the user-supplied plugin-struct.
+</P>
+
+<table cellpadding=10 width=100%><tr><td><table border=1 width=100%>
+  <tr><td width=50%> zzip_init_io </td>
+      <td width=50%> the recommended way to do things </td></tr>
+  <tr><td width=50%> zzip_get_default_io </td>
+      <td width=50%> used internally whenever you supply a null
+                     for the io-argument of a _ext_io()-call </td></tr>
+  <tr><td width=50%> zzip_get_default_ext </td>
+      <td width=50%> used internally but not exported </td></tr>
+</table></td></tr></table>
+
+
+<P>
+  And last some stdio-like replacements were build but these
+  happen to be actually just small wrappers around the other
+  posix-like magic-calls. It just offers some convenience
+  since wrappers like "SDL_rwops" tend to use a stringised
+  open-mode - and I took the occasion to fold the zzip-bits
+  for the _ext_io-calls right in there recognized via 
+  special extensions to the openmode-string of zzip_fopen().
+</P>
+
+<table cellpadding=10 width=100%><tr><td><table border=1 width=100%>
+  <tr><td width=50%> zzip_fopen </td>
+      <td width=50%> convert stringmode and call zzip_open_ext_io </td></tr>
+  <tr><td width=50%> zzip_fread </td>
+      <td width=50%> slower way to say zzip_read </td></tr>
+  <tr><td width=50%> zzip_fclose </td>
+      <td width=50%> a synonym of zzip_close </td></tr>
+</table></td></tr></table>
+
+<P>
+  For some reason, people did need the full set of function-calls()
+  to be working on zzip-wrappers too, so here they are - if the
+  ZZIP_FILE instance did wrap a real file, then the real posix-call
+  will be used, otherwise it is simulated on the compressed stream
+  with a zip-contained file - especially <code>seek()</code> can be 
+  a slow operation:
+  if the new point is later then just read out more bytes till we
+  hit that position but if it is an earlier point then rewind to the
+  beginning of the compressed data and start reading/decompression
+  until the position is met.
+</P>
+
+<table cellpadding=10 width=100%><tr><td><table border=1 width=100%>
+  <tr><td width=50%> zzip_rewind </td>
+      <td width=50%> magic for rewind() </td></tr>
+  <tr><td width=50%> zzip_tell </td>
+      <td width=50%> magic for tell() </td></tr>
+  <tr><td width=50%> zzip_seek </td>
+      <td width=50%> magic for seek() </td></tr>
+</table></td></tr></table>
+
+<P>
+  And last not least, there are few informative functions to
+  use function-calls to read parts of the opaque structures
+  of zzip-objects and their zzip-factory.
+</P>
+
+<table cellpadding=10 width=100%><tr><td><table border=1 width=100%>
+  <tr><td width=50%> zzip_dir_stat </td>
+      <td width=50%> a stat()-like thing on a file within a ZZIP_DIR </td></tr>
+  <tr><td width=50%> zzip_dir_real </td>
+      <td width=50%> check if ZZIP_DIR wraps a stat'able posix-dirent</td></tr>
+  <tr><td width=50%> zzip_file_real </td>
+      <td width=50%> check if ZZIP_FILE wraps a stat'able posix-file </td></tr>
+  <tr><td width=50%> zzip_realdir </td>
+      <td width=50%> if zzip_dir_real then return the posix-dirent </td></tr>
+  <tr><td width=50%> zzip_realfd </td>
+      <td width=50%> if zzip_file_real then return the posix-file </td></tr>
+  <tr><td width=50%> zzip_dirhandle </td>
+      <td width=50%> the attached ZZIP_DIR of compressed ZZIP_FILE </td></tr>
+  <tr><td width=50%> zzip_dirfd </td>
+      <td width=50%> the attached posix-file of ZZIP_DIR zip-file </td></tr>
+  <tr><td width=50%> zzip_set_error </td>
+      <td width=50%> set the last ZZIP_DIR error-code </td></tr>
+  <tr><td width=50%> zzip_error </td>
+      <td width=50%> get the last ZZIP_DIR error-code </td></tr>
+  <tr><td width=50%> zzip_strerror </td>
+      <td width=50%> convert a zzip_error into a readable string </td></tr>
+  <tr><td width=50%> zzip_strerror_of </td>
+      <td width=50%> combine both above zzip_strerror of zzip_error </td></tr>
+  <tr><td width=50%> zzip_errno </td>
+      <td width=50%> helper to wrap a zzip-error to a posix-errno </td></tr>
+  <tr><td width=50%> zzip_compr_str </td>
+      <td width=50%> helper to wrap a compr-number to a readable string
+                     </td></tr>
+  <tr><td width=50%> zzip_dir_free </td>
+      <td width=50%> internally called by zzip_dir_close if the ref-count 
+                     of the ZZIP_DIR has gone zero</td></tr>
+  <tr><td width=50%> zzip_freopen </td>
+      <td width=50%> to reuse the ZZIP_DIR from another ZZIP_FILE so it does
+                     not need to be parsed again </td></tr>
+  <tr><td width=50%> zzip_open_shared_io </td>
+      <td width=50%> the ext/io cousin but it does not close the old ZZIP_FILE
+                     and instead just shares the ZZIP_DIR if possible</td></tr>
+</table></td></tr></table>
+
diff --git a/docs/zzip-extio.htm b/docs/zzip-extio.htm
new file mode 100644 (file)
index 0000000..86524ca
--- /dev/null
@@ -0,0 +1,185 @@
+<h2> ZZIP-EXT/IO </h2> Customizing the file access
+
+<!--border--><date>15. July 2002 </date>
+
+<h3> The EXT/IO calls </h3>
+
+<P>
+  There were quite some requests from game developers and graphics-apps
+  developers who wanted various extensions to be included into the
+  <a href="zziplib.html">zziplib library</a>, but most of them were
+  only of specific usage. After some discussions we came up with a
+  model to customize the <a href="zziplib.html">zziplib library</a>
+  calls in a number of ways - and adding two or three arguments to
+  the zzip_* calls. The standard <a href="zziplib.html">zziplib library</a>
+  will actually call these *_ext_io functions with these extra arguments
+  to be set to zero.
+</P><P>
+  The EXT feature describes a way to customize the extensions used in
+  the magic wrapper to find a .ZIP file. It turned out that there are
+  quite a number of applications that did chose the zip file format as
+  their native document format and where just the file extension had
+  been changed. This includes file types like Quake3 ".PK3" files from
+  ID Software, the Java library files called ".JAR", and lately the 
+  OpenOffice-6 (resp. StarOffice-6) documents which carry xml-files along.
+  Just build a zero-termined string-list of file-extensions and submit it
+  to the _ext_io calls to let the <a href="zziplib.html">zziplib</a> find
+  parts of those zip-documents automagically.
+</P><P>
+  In quite some of these cases, it is very benefical to make use of the
+  o_modes functionality that allows to submit extra bit-options into
+  the <a href="zziplib.html">zziplib</a> - this includes options like
+  <code>ZZIP_PREFERZIP</code> or even <code>ZZIP_ONLYZIP</code> which
+  modifies the default behaviour of looking for real files first instead
+  of some within a zipped directory tree. Other bit-options include
+  <code>ZZIP_CASELESS</code> to imitate win32-like filematching for a
+  zipped filetree.
+</P><P>
+  Other wishes on <a href="zziplib.html">zziplib</a> circulated around
+  <a href="zzip-xor.html">obfuscation</a> or access to zip-files wrapped 
+  in other data areas including encrpyted resources from other applications. 
+  This has been adressed with the IO-handlers that you can explicitly 
+  submit to the *_ext_io functions - the default will be posix-IO 
+  open/read/write and seek/tell. An application using 
+  <a href="zziplib.html">zziplib</a> can divert these to its own set of
+  these calls - and it only needs to declare them on opening a zipped file.
+</P>
+
+<h3> The EXT stringlist </h3>
+
+<P>
+  Declaring an EXT stringlist is very simple as it is simply a 
+  list of strings, the <a href="zziplib.html">zziplib</a> provides
+  you with a double-const <code>zzip_strings_t</code> type to help
+  you move a global declaration into the writeonly segment of your
+  app - it turned out that about all developers wanted just some
+  extensions on the default and they were fine with having them
+  global-const for their application, nothing like dynamically
+  modifying them. Well, you are still allowed to make it fully
+  dynamic... if you find a use case for that.
+</P><P>
+  Extending the magic zip-extensions is just done by adding the 
+  additional extensions to be recognized - just remember to add
+  the uppercased variants too since those will be needed on
+  (unx-like) filesystems that are case-sensitive. In the internet
+  age, quite some downloaded will appear in uppercased format since
+  the other side declared it as that and that other end was happy
+  with it as being a (w32-like) case-insensitive server. Therefore,
+  it should look like <pre>
+     static zzip_strings_t my_ext[] = { ".zip", ".ZIP", ".jar", ".JAR", 0 };
+  </pre>
+</P><P>
+  There is one frequently asked question in this area - how to open
+  a zipped file as "test.zip/README" instead of "test/README". Other
+  than some people might expect, the library will not find it - if
+  you want to have that one needs a fileext list that contains the
+  empty string - not the zero string, an empty string that is. It
+  looks like <pre>
+     static zzip_strings_t my_ext[] = { ".zip", ".ZIP", "", 0 };
+  </pre>
+</P><P>
+  And last not least, people want to tell the libary to not try to
+  open a real file that lives side by side with the same path as the
+  file path that can be matched by the zziplib. Actually, the magic
+  wrappers were never meant to be used like - the developer should
+  have used zzip_dir_* functions to open a zip-file and the 
+  zzip_file_* functions to read entries from that zip-file. However,
+  the magic-wrappers look rather more familiar, and so you will find
+  now a bit-option ZZIP_ONLYZIP that can be passed down to the _ext_io
+  variants of the magic-wrapper calls, and a real-file will never get
+  tested for existance. Actually, I would rather recommend that for
+  application data the option ZZIP_PREFERZIP, so that one can enter
+  debugging mode by unpacking the zip-file as a real directory tree
+  in the place of the original zip.
+</P>
+
+<h3> The IO handlers </h3>
+
+<P>
+  While you will find the zzip_plugin_io_t declared in the zziplib
+  headers, you are not advised to make much assumptions about their
+  structure. Still we gone the path of simplicity, so you can use
+  a global static for this struct too just like one can do for the
+  EXT-list. This again mimics the internals of zziplib. There is
+  even a helper function zzip_init_io that will copy the zziplib
+  internal handlers to your own handlers-set. Actually, this is
+  barely needed since the zziplib library will not check for nulls
+  in the plugin_io structure, all handlers must be filled, and the
+  zziplib routines call them unconditionally - that's simply 
+  because a conditional-call will be ten times slower than an
+  unconditional call which adds mostly just one or two cpu cycles
+  in the place so you won't ever notice zziplib to be anywhat
+  slower than before adding IO-handlers.
+</P><P>
+  However, you better instantiate your handlers in your application
+  and call that zzip_init_io on that instance to have everything
+  filled, only then modify the entry you actually wish to have
+  modified. For <a href="zzip-xor.html">obfuscation</a> this
+  will mostly be just the <code>read()</code> routine. But one can
+  also use IO-handlers to wrap zip-files into another data part
+  for which one (also) wants to modify the open/close routines
+  as well.
+</P><P>
+  Therefore, you can modify your normal stdio code to start using
+  zipped files by exchaning the fopen/fread/fclose calls by their
+  magic counterparts, i.e. <pre>
+    // FILE* file = fopen ("test/README", "rb");
+    ZZIP_FILE* file = zzip_fopen ("test/README", "rb");
+    // while (0 &lt; fread (buffer, 1, buflen, file))) 
+    while (0 &lt; zzip_fread (buffer, 1, buflen, file)))
+       { do something }
+    // fclose (file);
+    zzip_fclose (file);
+  </pre>
+   and you then need to prefix this code with some additional 
+   code to support your own EXT/IO set, so the code will finally
+   look like <pre>
+    /* use .DAT extension to find some files */
+    static zzip_strings_t ext[] = { ".dat", ".DAT", "", 0 }; 
+    /* add obfuscation routine - see zzxorcat.c examples */
+    static zzip_plugin_io_t io;
+    zzip_init_io (&amp; io, 0);
+    io.read = xor_read; 
+    /* and the rest of the code, just as above, but with ext/io */
+    ZZIP_FILE* file = zzip_open_ext_io ("test/README", O_RDONLY|O_BINARY,
+                                        ZZIP_ONLYZIP|ZZIP_CASELESS, ext, io);
+    while (0 &lt; zzip_fread (buffer, 1, buflen, file)))
+        { do something }
+    zzip_fclose (file);
+  </pre>   
+</P>
+
+<h3> Finally </h3>
+
+<P>
+   What's more to it? Well, if you have some ideas then please mail me
+   about it - don't worry, I'll probably reject it to be part of the
+   standard zziplib dll, but perhaps it is worth to be added as a
+   configure option and can help others later, and even more perhaps
+   it can be somehow generalized just as the ext/io features have been
+   generalized now. In most respects, this ext/io did not add much
+   code to the <a href="zziplib.html">zziplib</a> - the posix-calls
+   in the implemenation, like <code>"read(file)"</code> were simply
+   exchanged with <code>"zip-&gt;io-&gt;read(file)"</code>, and the 
+   old <code>"zzip_open(name,mode)"</code> call is split up - the old
+   entry still persists but directly calls 
+   <code>"zzip_open_ext_io(name,mode,0,0,0)"</code> which has the
+   old implementation code with just one addition: when the ZIP_FILE
+   handle is created, it uses the transferred io-handlers (or the
+   default ones if io==0), and initialized the io-member of that
+   structure for usage within the <code>zzip_read</code> calls.
+</P><P>
+   This adds just a few bytes to the libs and just consumes additional 
+   cpu cycles that can be rightfully called to be negligable (unlike
+   most commerical vendors will tell you when they indeed want to
+   tell you that for soooo many new features you have to pay a price).
+   It makes for greater variability without adding fatness to the
+   core in the default case, this is truly efficient I'd say. Well,
+   call this a German desease :-)=) ... and again, if you have another
+   idea, write today... or next week.
+</P>
+
+
+
+
+
diff --git a/docs/zzip-sdl-rwops.htm b/docs/zzip-sdl-rwops.htm
new file mode 100644 (file)
index 0000000..fa8f047
--- /dev/null
@@ -0,0 +1,85 @@
+<h2> SDL rwops </h2> Example to make an SDL_rwops interface.
+
+<p><small> some <b>MSVC</b> help in 
+   <a href="README.MSVC6">README.MSVC6</a> and
+   <a href="README.SDL">README.SDL</a>
+</small></p>
+
+<!--border--> <date> 19. Aug 2001 </date>
+
+<h3> Source </h3>
+
+<P>
+ The example sources of the <a href="zziplib.html">zziplib library</a>
+ are usually put under the <a href="COPYING.ZLIB">ZLIB license</a> so 
+ that you can reuse the code freely in your own projects. Here we talk
+ about the example that might be most useful for 
+ <a href="http://libsdl.org">SDL</a> based programs.
+ Just copy the two files 
+ <a href="SDL_rwops_zzip.h">SDL_rwops_zzip.h</a>
+ and
+ <a href="SDL_rwops_zzip.c">SDL_rwops_zzip.c</a>
+ to the directory with your other project sources, and make sure
+ to link it somehow to your programs. I did not make the effort to
+ create a seperate library out of it - it would just export one
+ single function <tt>SDL_RWFromZZIP</tt> that has the same call-synopsis
+ like <tt>SDL_RWFromFile</tt> (but it can not (yet) write a zip-file).
+</P>
+
+<P>
+ The source file <a href="SDL_rwops_zzip.c">SDL_rwops_zzip.c</a> is
+ quite short - it just stores a ZZIP_FILE handle in the userdata
+ field of the <tt>SDL_rwops</tt> structure. The SDL'rwop calls will then
+ fetch that pointer and call the corresponding functions from the
+ <a href="zziplib.html">zziplib library</a>. Most of the glue code
+ is in the <tt>SDL_RWFromZZIP</tt> function that allocates an 
+ <tt>SDL_rwops</tt> structure and fills the handler-functions 
+ into the callback fields.
+</P>
+
+<h3> Usage </h3>
+
+<P>
+ If you link this file to your project, remember that your executables
+ do now have additional dependencies - not only -lzzip to link with
+ the <a href="zziplib.html">zziplib library</a> - do not forget to
+ link with zlib library via -lz. Of course, there is a lib-config
+ script that you can use: `zzip-config --libs` will return these
+ linker-infos (unless you have a native-windows system - it is 
+ shell-script).
+</P>
+
+<P>
+ As an example, replace that <tt>SDL_RWFromFile</tt> that accesses your
+ game-graphic files - these files are stored in shared/myapp
+ of course where they belong. When you've done that
+ then go to X/share/myapp and 
+ <pre>&nbsp;&nbsp;&nbsp;
+ `(cd graphics/ && zip -9r ../graphics.zip .)` </pre>
+ and rename the graphics/ subfolder - and still all your files
+ are found: a filepath like X/shared/graphics/game/greetings.bmp 
+ will open X/shared/graphics.zip and return the zipped file 
+ game/greetings.bmp in the zip-archive (for reading that is).
+</P>
+
+<h3> Test </h3>
+
+<P>
+ The <a href="zziplib.html">zziplib</a> configure script does not
+ look for <a href="http://libsdl.org">SDL</a>. If you know that
+ you have <a href="http://libsdl.org">SDL</a> installed 
+ then you can check this <tt>SDL_rwops</tt> example by using
+ <code><nobr>`make testsdl`</nobr></code>. This will compile the
+ two source files <a href="SDL_rwops_zzip.c">SDL_rwops_zzip.c</a>
+ and <a href="SDL_rwops_zzcat.c">SDL_rwops_zzcat.c</a> to be linked
+ together into an executable called <code>zzcatsdl</code>. The test
+ will continue with a <code><nobr>`zzcatsdl test/README`</nobr></code> 
+ - just like it is done for <code><nobr>`make test3`</nobr></code>.
+</P>
+<P>
+ The corresponding section in the <a href="Makefile.am">Makefile.am</a>
+ is also an example how to use lib-config scripts to build files. Here
+ there is no build-processing that had been tweaked much by automake/autoconf.
+ Just use sdl-config and zzip-config to add the needed flags.
+</P>
+