/** \page usage Usage

This page provides general information on %QuaZip usage. See classes
QuaZip and QuaZipFile for the detailed documentation on what can
%QuaZip do and what it can't do. Also, reading comments in the zip.h and
unzip.h files (taken from the original ZIP/UNZIP package) is always a
good idea too. After all, %QuaZip is just a wrapper with a few
convenience extensions and reimplementations.

\section CMake

To get started, as it is usual with modern CMake, you just need
something like this in your CMakeLists.txt:

\verbatim
find_package(QuaZip-Qt5)
target_link_libraries(whatever-your-target-is QuaZip::QuaZip)
\endverbatim

Or, if you prefer to add %QuaZip sources directly to your project
(e. g. as a Git submodule):
\verbatim
add_subdirectory(quazip)
target_link_libraries(whatever-your-target-is QuaZip::QuaZip)
\endverbatim

In the latter case, you may want to set BUILD_SHARED_LIBS to NO
to link statically.

In all cases, if %QuaZip is linked statically, it automatically
defines QUAZIP_STATIC whenever your link to it, which disables
dllimports that would lead to confusing errors (at least on Windows)
otherwise.

If, for some weird reason, you decide to add %QuaZip sources to your
project directly (skipping CMake), or link it statically and then
link it to your project without CMake, you may need to define
QUAZIP_STATIC manually to avoid problems with dllimports.

%QuaZip uses SameMajorVersion compatibility mode, so you can have,
say, %QuaZip 1.x and %QuaZip 2.x (in some future, when there is such a thing)
installed in parallel, and then pass the required version to
\c find_package. As long as the major version matches, it will be found.

\section Flatpak

%Quazip can be used in Flatpak YAML manifests as such:

\verbatim
modules:
  - name: quazip
    buildsystem: cmake-ninja
    builddir: true
    config-opts:
      - -DCMAKE_BUILD_TYPE=MinSizeRel
    sources:
      - type: archive
        url: https://github.com/stachenov/quazip/archive/v1.1.tar.gz
        sha256: 54edce9c11371762bd4f0003c2937b5d8806a2752dd9c0fd9085e90792612ad0
      - type: shell
        commands:
          - sed -i 's|${CMAKE_ROOT}/Modules|share/cmake|' CMakeLists.txt
\endverbatim

\section terminology Terminology

“%QuaZip” means the whole library or the \c QuaZip class, depending
on the context.

“ZIP/UNZIP API” or “Minizip” means the original API of the Gilles
Vollant's ZIP/UNZIP package. It was slightly modified to better
integrate with Qt. These modifications are not source or binary
compatible with the official Minizip release, which means you can't
just drop the newer Minizip version into %QuaZip sources and make it
work.

“ZIP”, “ZIP archive” or “ZIP file” means any ZIP archive. Typically
this is a plain file with “.zip” (or “.ZIP”) file name suffix, but it
can also be any seekable QIODevice (say, QBuffer, but not
QTcpSocket).

“A file inside archive”, “a file inside ZIP” or something like that
means file either being read or written from/to some ZIP archive.

\section API

The main classes are QuaZip and QuaZipFile, and there's JlCompress
that contains a lot of high-level utility methods (think of it
as the Facade Pattern for the most common uses).

Finally, there is QuaCompress which is a Fluent API wrapper of JlCompress.

QuaZip is a class representing ZIP archive, QuaZipFile represents a
file inside archive and subclasses QIODevice as well. One limitation
is that there can be only one instance of QuaZipFile per QuaZip
instance, which kind of makes it confusing why there are two classes
instead of one. This is actually no more than an API design mistake
kept for backwards compatibility.

\section general-usage General usage

In general, the process looks like this:

-# Open or create an archive with a QuaZip instance.
-# Open or create a file in the archive with a QuaZipFile instance.
-# Perform reading or writing.
-# Close the QuaZipFile instance.
-# Repeat steps 2–4 for other files if needed.
-# Close the QuaZip instance.

See the “qztest” subdirectory for examples. TestQuaZipFile::zipUnzip()
is a good place to start.

\section error-handling Error handling

Almost any call to ZIP/UNZIP API return some error code. Most of the
original API's error checking could be done in this wrapper as well,
but it would cause unnecessary code bloating without any benefit. So,
%QuaZip only checks for situations that ZIP/UNZIP API can not check
for. For example, ZIP/UNZIP API has no “ZIP open mode” concept
because read and write modes are completely separated. On the other
hand, to avoid creating classes like “QuaZipReader”, “QuaZipWriter”
or something like that, %QuaZip introduces “ZIP open mode” concept
instead, thus making it possible to use one class (QuaZip) for both
reading and writing. But this leads to additional open mode checks
which are not done in ZIP/UNZIP package.

Therefore, error checking is two-level (%QuaZip's level and ZIP/UNZIP
API level), which sometimes can be confusing, so here are some
advices on how the error checking should be properly done:

- Both QuaZip and QuaZipFile have getZipError() function, which return
  error code of the last ZIP/UNZIP API call. Most function calls
  reset error code to UNZ_OK on success and set error code on
  failure. Some functions do not reset error code. Most of them are
  \c const and do not access ZIP archive in any way. Some, on the
  other hand, \em do access ZIP archive, but do not reset or set
  error code. For example, QuaZipFile::pos() function. Such functions
  are explicitly marked in the documentation.
- Most functions have their own way to report errors, by returning a
  null string, negative value or \c false. If such a function returns
  error value, call getZipError() to get more information about
  error. See “zip.h” and “unzip.h” of the ZIP/UNZIP package for error
  codes.
- If the function returns error-stating value (like \c false), but
  getZipError() returns UNZ_OK, it means that you did something
  obviously wrong. For example, tried to write in the archive open
  for reading or not open at all. You better just not do that!
  Most functions also issue a warning using qWarning() function in
  such cases. See documentation for a specific function for details
  on when it should not be called.

I know that this is somewhat messy, but I could not find a better way
to do all the error handling back in 2005, and it's too late to change
anything now. A major API redesign is needed, but not planned in any
foreseeable future yet.
*/
