From 842295b6b175789ed9b6d1b291da8854de5714ff Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sat, 1 Mar 2025 10:17:25 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E7=B1=BB=E4=BB=A5=E5=8A=A0=E8=BD=BD=E9=BB=98=E8=AE=A4=E5=AD=97?= =?UTF-8?q?=E4=BD=93=E8=AE=BE=E7=BD=AE=EF=BC=8C=E5=B9=B6=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=AD=97=E4=BD=93=E6=9B=BF=E6=8D=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- config.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ config.hpp | 11 +++++++++++ dllmain.cpp | 11 +++++++++-- 4 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 config.cpp create mode 100644 config.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index be8b9df..44ec7a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ set(ENABLE_ICONV OFF CACHE BOOL "Libiconv is not needed.") add_subdirectory(utils) include_directories("${CMAKE_CURRENT_SOURCE_DIR}/utils") -add_library(jewena_patch SHARED dllmain.cpp) +add_library(jewena_patch SHARED dllmain.cpp config.hpp config.cpp) target_link_libraries(jewena_patch "${DETOURS_LIB}") target_link_libraries(jewena_patch utils) diff --git a/config.cpp b/config.cpp new file mode 100644 index 0000000..fc84d6b --- /dev/null +++ b/config.cpp @@ -0,0 +1,48 @@ +#include "config.hpp" +#include "fileop.h" +#include "file_reader.h" +#include "malloc.h" + +#include +#if _WIN32 +#include +#endif + +bool Config::Load(std::string path) { + if (!fileop::exists(path)) { + return false; + } + int fd = 0; + int err = fileop::open(path, fd, O_RDONLY, _SH_DENYRW, _S_IREAD); + if (err < 0) { + return false; + } + FILE* f = fileop::fdopen(fd, "rb"); + if (!f) { + fileop::close(fd); + return false; + } + auto reader = create_file_reader(f, 0); + char* line = nullptr; + size_t line_size = 0; + while (!file_reader_read_line(reader, &line, &line_size)) { + std::string l(line, line_size); + free(line); + line = nullptr; + line_size = 0; + size_t comment_pos = l.find_first_of('#'); + if (comment_pos != std::string::npos) { + l = l.substr(0, comment_pos); + } + size_t eq_pos = l.find_first_of('='); + if (eq_pos == std::string::npos) { + continue; + } + std::string key = l.substr(0, eq_pos); + std::string value = l.substr(eq_pos + 1); + configs[key] = value; + } + free_file_reader(reader); + fileop::fclose(f); + return true; +} diff --git a/config.hpp b/config.hpp new file mode 100644 index 0000000..1cb4681 --- /dev/null +++ b/config.hpp @@ -0,0 +1,11 @@ +#include +#include + +class Config { + public: + std::unordered_map configs; + Config() { + configs["defaultFont"] = "微软雅黑"; + } + bool Load(std::string path); +}; diff --git a/dllmain.cpp b/dllmain.cpp index 19c40f5..b4d71b9 100644 --- a/dllmain.cpp +++ b/dllmain.cpp @@ -1,10 +1,13 @@ #include +#include "config.hpp" #include "detours.h" #include #include "wchar_util.h" static HFONT(WINAPI *TrueCreateFontW)(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD dwItalic, DWORD dwUnderline, DWORD dwStrikeOut, DWORD dwCharSet, DWORD dwOutPrecision, DWORD dwClipPrecision, DWORD dwQuality, DWORD dwPitchAndFamily, LPCWSTR lpFaceName) = CreateFontW; static HFONT(WINAPI *TrueCreateFontA)(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD dwItalic, DWORD dwUnderline, DWORD dwStrikeOut, DWORD dwCharSet, DWORD dwOutPrecision, DWORD dwClipPrecision, DWORD dwQuality, DWORD dwPitchAndFamily, LPCSTR lpFaceName) = CreateFontA; +static Config config; +static std::wstring defaultFont; char* to_utf8(char* target, const char* source, UINT cp) { int count = MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, source, -1, NULL, 0); @@ -42,7 +45,7 @@ static PVOID h = nullptr; HFONT WINAPI HookedCreateFontW(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD dwItalic, DWORD dwUnderline, DWORD dwStrikeOut, DWORD dwCharSet, DWORD dwOutPrecision, DWORD dwClipPrecision, DWORD dwQuality, DWORD dwPitchAndFamily, LPCWSTR lpFaceName) { std::wstring name(lpFaceName); if (name == L"Meiryo") { - lpFaceName = L"微软雅黑"; + lpFaceName = defaultFont.c_str(); } return TrueCreateFontW(nHeight, nWidth, nEscapement, nOrientation, fnWeight, dwItalic, dwUnderline, dwStrikeOut, dwCharSet, dwOutPrecision, dwClipPrecision, dwQuality, dwPitchAndFamily, lpFaceName); } @@ -53,7 +56,7 @@ HFONT WINAPI HookedCreateFontA(int nHeight, int nWidth, int nEscapement, int nOr for (int i = 0; i < 4; i++) { if (wchar_util::str_to_wstr(font, lpFaceName, cp[i])) { if (font == L"Meiryo") { - font = L"微软雅黑"; + font = defaultFont; } return TrueCreateFontW(nHeight, nWidth, nEscapement, nOrientation, fnWeight, dwItalic, dwUnderline, dwStrikeOut, dwCharSet, dwOutPrecision, dwClipPrecision, dwQuality, dwPitchAndFamily, font.c_str()); } @@ -65,6 +68,10 @@ HFONT WINAPI HookedCreateFontA(int nHeight, int nWidth, int nEscapement, int nOr } extern "C" __declspec(dllexport) void Attach() { + config.Load("config.txt"); + if (!wchar_util::str_to_wstr(defaultFont, config.configs["defaultFont"], CP_UTF8)) { + defaultFont = L"微软雅黑"; + } DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); h = GetHandle(); From 9eee8ae1d910e0a09645c7847438f3610529b0f9 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Mon, 3 Mar 2025 19:41:17 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=99=9A=E6=8B=9F?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E7=B3=BB=E7=BB=9F=EF=BC=88VFS=EF=BC=89?= =?UTF-8?q?=E7=B1=BB=E4=BB=A5=E6=94=AF=E6=8C=81=E5=8E=8B=E7=BC=A9=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E8=AF=BB=E5=8F=96=E5=92=8C=E7=AE=A1=E7=90=86?= =?UTF-8?q?=EF=BC=8C=E6=9B=B4=E6=96=B0CMake=E9=85=8D=E7=BD=AE=E4=BB=A5?= =?UTF-8?q?=E5=8C=85=E5=90=ABlibzip=E5=AD=90=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .gitmodules | 3 + CMakeLists.txt | 27 +- dllmain.cpp | 199 +++++ include/zconf.h | 545 +++++++++++++ include/zlib.h | 1938 +++++++++++++++++++++++++++++++++++++++++++++++ lib/zlib.lib | Bin 0 -> 195498 bytes libzip | 1 + utils | 2 +- vfs.cpp | 161 ++++ vfs.hpp | 26 + 11 files changed, 2901 insertions(+), 2 deletions(-) create mode 100644 include/zconf.h create mode 100644 include/zlib.h create mode 100644 lib/zlib.lib create mode 160000 libzip create mode 100644 vfs.cpp create mode 100644 vfs.hpp diff --git a/.gitignore b/.gitignore index 567609b..6f31401 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build/ +.vscode/ diff --git a/.gitmodules b/.gitmodules index 2676665..9572423 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "utils"] path = utils url = https://github.com/lifegpc/c-utils +[submodule "libzip"] + path = libzip + url = https://github.com/nih-at/libzip diff --git a/CMakeLists.txt b/CMakeLists.txt index 44ec7a2..f32cc2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,8 +14,33 @@ set(ENABLE_ICONV OFF CACHE BOOL "Libiconv is not needed.") add_subdirectory(utils) include_directories("${CMAKE_CURRENT_SOURCE_DIR}/utils") -add_library(jewena_patch SHARED dllmain.cpp config.hpp config.cpp) +set(ENABLE_COMMONCRYPTO OFF CACHE BOOL "CommonCrypto is not needed.") +set(ENABLE_GNUTLS OFF CACHE BOOL "GnuTLS is not needed.") +set(ENABLE_MBEDTLS OFF CACHE BOOL "MbedTLS is not needed.") +set(ENABLE_OPENSSL OFF CACHE BOOL "OpenSSL is not needed.") +set(ENABLE_WINDOWS_CRYPTO OFF CACHE BOOL "Schannel is not needed.") + +set(ENABLE_BZIP2 OFF CACHE BOOL "Bzip2 is not needed.") +set(ENABLE_LZMA OFF CACHE BOOL "Lzma is not needed.") +set(ENABLE_ZSTD OFF CACHE BOOL "Zstd is not needed.") + +set(BUILD_TOOLS OFF CACHE BOOL "Tools are not needed.") +set(BUILD_REGRESS OFF CACHE BOOL "Tests are not needed.") +set(BUILD_OSSFUZZ OFF CACHE BOOL "Fuzz tests are not needed.") +set(BUILD_EXAMPLES OFF CACHE BOOL "Examples are not needed.") +set(BUILD_DOC OFF CACHE BOOL "Documentation is not needed.") + +set(BUILD_SHARED_LIBS OFF CACHE BOOL "Static library is needed.") +set(LIBZIP_DO_INSTALL OFF CACHE BOOL "Installation is not needed.") +set(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" CACHE PATH "Zlib is needed.") + +find_package(ZLIB REQUIRED) +add_subdirectory("libzip") + +add_library(jewena_patch SHARED dllmain.cpp config.hpp config.cpp vfs.hpp vfs.cpp) target_link_libraries(jewena_patch "${DETOURS_LIB}") target_link_libraries(jewena_patch utils) +target_link_libraries(jewena_patch zip) +target_link_libraries(jewena_patch shlwapi.lib) add_executable(jewena-chs WIN32 main.cpp winres.rc jewena-chs.exe.manifest) diff --git a/dllmain.cpp b/dllmain.cpp index b4d71b9..70a02bd 100644 --- a/dllmain.cpp +++ b/dllmain.cpp @@ -2,12 +2,146 @@ #include "config.hpp" #include "detours.h" #include +#include #include "wchar_util.h" +#include "vfs.hpp" +#include "str_util.h" +#include "fileop.h" +#include +#include static HFONT(WINAPI *TrueCreateFontW)(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD dwItalic, DWORD dwUnderline, DWORD dwStrikeOut, DWORD dwCharSet, DWORD dwOutPrecision, DWORD dwClipPrecision, DWORD dwQuality, DWORD dwPitchAndFamily, LPCWSTR lpFaceName) = CreateFontW; static HFONT(WINAPI *TrueCreateFontA)(int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight, DWORD dwItalic, DWORD dwUnderline, DWORD dwStrikeOut, DWORD dwCharSet, DWORD dwOutPrecision, DWORD dwClipPrecision, DWORD dwQuality, DWORD dwPitchAndFamily, LPCSTR lpFaceName) = CreateFontA; +static HANDLE(WINAPI *TrueCreateFileW)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) = CreateFileW; +static BOOL(WINAPI *TrueReadFile)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) = ReadFile; +static BOOL(WINAPI *TrueCloseHandle)(HANDLE hObject) = CloseHandle; +static DWORD(WINAPI *TrueGetFileSize)(HANDLE hFile, LPDWORD lpFileSizeHigh) = GetFileSize; +static DWORD(WINAPI *TrueSetFilePointer)(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) = SetFilePointer; +static decltype(FindFirstFileExW)* OriginalFindFirstFileExW = FindFirstFileExW; +static decltype(FindNextFileW)* OriginalFindNextFileW = FindNextFileW; +static decltype(FindClose)* OriginalFindClose = FindClose; + static Config config; static std::wstring defaultFont; +static VFS vfs; + +struct CustomFindContext { + std::vector entries; + size_t current_index; +}; + +HANDLE WINAPI HookedFindFirstFileExW( + LPCWSTR lpFileName, + FINDEX_INFO_LEVELS fInfoLevelId, + LPVOID lpFindFileData, + FINDEX_SEARCH_OPS fSearchOp, + LPVOID lpSearchFilter, + DWORD dwAdditionalFlags +) { + std::wstring filename_w(lpFileName); + std::string filename_utf8; + wchar_util::wstr_to_str(filename_utf8, filename_w, CP_UTF8); + + // 解析目录和模式 + std::string dir_part = fileop::dirname(filename_utf8); + std::string pattern = fileop::basename(filename_utf8); + + // 标准化路径,判断是否为目标目录 + std::string abs_dir = fileop::isabs(dir_part) ? dir_part : fileop::join(vfs.GetBasePath(), dir_part); + std::string base = fileop::join(vfs.GetBasePath(), ""); // 确保base_path以/结尾 + + if (abs_dir != vfs.GetBasePath()) { + // 非目标目录,调用原始函数 + return OriginalFindFirstFileExW(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); + } + + // 收集实际文件系统的条目 + HANDLE hFindReal = OriginalFindFirstFileExW(lpFileName, fInfoLevelId, lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); + std::vector real_entries; + WIN32_FIND_DATAW data; + if (hFindReal != INVALID_HANDLE_VALUE) { + while (OriginalFindNextFileW(hFindReal, &data)) { + real_entries.push_back(data); + } + OriginalFindClose(hFindReal); + } + + // 转换模式为宽字符 + std::wstring wpattern; + wchar_util::str_to_wstr(wpattern, pattern, CP_UTF8); + + // 收集虚拟条目 + std::vector virtual_entries; + for (const auto& entry : vfs.files) { + std::string file_path = entry.first; + std::vector components = str_util::str_splitv(file_path, "\\"); + if (components.empty()) continue; + + if (components.size() == 1) { + // 文件条目 + std::wstring wname; + wchar_util::str_to_wstr(wname, components[0], CP_UTF8); + if (PathMatchSpecW(wname.c_str(), wpattern.c_str())) { + WIN32_FIND_DATAW vdata = {0}; + wcsncpy(vdata.cFileName, wname.c_str(), MAX_PATH); + vdata.dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE; + vdata.nFileSizeLow = static_cast(entry.second & 0xFFFFFFFF); + vdata.nFileSizeHigh = static_cast(entry.second >> 32); + virtual_entries.push_back(vdata); + } + } else { + // 目录条目 + std::wstring wdir; + wchar_util::str_to_wstr(wdir, components[0], CP_UTF8); + if (PathMatchSpecW(wdir.c_str(), wpattern.c_str())) { + bool dir_exists = std::any_of(real_entries.begin(), real_entries.end(), + [&](const WIN32_FIND_DATAW& d) { + return (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + _wcsicmp(d.cFileName, wdir.c_str()) == 0; + }); + if (!dir_exists) { + WIN32_FIND_DATAW vdata = {0}; + wcsncpy(vdata.cFileName, wdir.c_str(), MAX_PATH); + vdata.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; + virtual_entries.push_back(vdata); + } + } + } + } + + // 合并条目 + std::vector all_entries; + all_entries.reserve(real_entries.size() + virtual_entries.size()); + all_entries.insert(all_entries.end(), real_entries.begin(), real_entries.end()); + all_entries.insert(all_entries.end(), virtual_entries.begin(), virtual_entries.end()); + + // 创建上下文 + CustomFindContext* ctx = new CustomFindContext{all_entries, 0}; + if (!all_entries.empty()) { + *static_cast(lpFindFileData) = all_entries[1]; + ctx->current_index = 2; + } + return reinterpret_cast(ctx); +} + +BOOL WINAPI HookedFindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData) { + CustomFindContext* ctx = reinterpret_cast(hFindFile); + if (ctx && ctx->current_index < ctx->entries.size()) { + *lpFindFileData = ctx->entries[ctx->current_index++]; + return TRUE; + } + SetLastError(ERROR_NO_MORE_FILES); + return FALSE; +} + +BOOL WINAPI HookedFindClose(HANDLE hFindFile) { + CustomFindContext* ctx = reinterpret_cast(hFindFile); + if (ctx) { + delete ctx; + return TRUE; + } + return OriginalFindClose(hFindFile); +} char* to_utf8(char* target, const char* source, UINT cp) { int count = MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, source, -1, NULL, 0); @@ -67,18 +201,75 @@ HFONT WINAPI HookedCreateFontA(int nHeight, int nWidth, int nEscapement, int nOr return TrueCreateFontA(nHeight, nWidth, nEscapement, nOrientation, fnWeight, dwItalic, dwUnderline, dwStrikeOut, dwCharSet, dwOutPrecision, dwClipPrecision, dwQuality, dwPitchAndFamily, lpFaceName); } +HANDLE WINAPI HookedCreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { + if (vfs.ContainsFile(lpFileName)) { + return vfs.CreateFileW(lpFileName); + } + return TrueCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); +} + +BOOL WINAPI HookedReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) { + if (vfs.ContainsHandle(hFile)) { + if (lpOverlapped) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + return vfs.ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead); + } + return TrueReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); +} + +BOOL WINAPI HookedCloseHandle(HANDLE hObject) { + if (vfs.ContainsHandle(hObject)) { + vfs.CloseHandle(hObject); + return TRUE; + } + return TrueCloseHandle(hObject); +} + +DWORD WINAPI HookedGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) { + if (vfs.ContainsHandle(hFile)) { + return vfs.GetFileSize(hFile, lpFileSizeHigh); + } + return TrueGetFileSize(hFile, lpFileSizeHigh); +} + +DWORD WINAPI HookedSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) { + if (vfs.ContainsHandle(hFile)) { + return vfs.SetFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod); + } + return TrueSetFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod); +} + extern "C" __declspec(dllexport) void Attach() { config.Load("config.txt"); if (!wchar_util::str_to_wstr(defaultFont, config.configs["defaultFont"], CP_UTF8)) { defaultFont = L"微软雅黑"; } + if (!vfs.AddArchive("jewena-chs.dat")) { + MessageBoxW(NULL, L"无法打开 jewena-chs.dat。请检查文件是否存在", L"错误", MB_ICONERROR); + ExitProcess(1); + return; + } DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); h = GetHandle(); DetourAttach(&h, (PVOID)jis_to_utf8); DetourAttach(&TrueCreateFontW, HookedCreateFontW); DetourAttach(&TrueCreateFontA, HookedCreateFontA); + DetourAttach(&TrueCreateFileW, HookedCreateFileW); + DetourAttach(&TrueReadFile, HookedReadFile); + DetourAttach(&TrueCloseHandle, HookedCloseHandle); + DetourAttach(&TrueGetFileSize, HookedGetFileSize); + DetourAttach(&TrueSetFilePointer, HookedSetFilePointer); + DetourAttach(&OriginalFindFirstFileExW, HookedFindFirstFileExW); + DetourAttach(&OriginalFindNextFileW, HookedFindNextFileW); + DetourAttach(&OriginalFindClose, HookedFindClose); DetourTransactionCommit(); +#if _DEBUG + while( !::IsDebuggerPresent() ) + ::Sleep( 1000 ); +#endif } extern "C" __declspec(dllexport) void Detach() { @@ -88,6 +279,14 @@ extern "C" __declspec(dllexport) void Detach() { DetourDetach(&h, (PVOID)jis_to_utf8); DetourDetach(&TrueCreateFontW, HookedCreateFontW); DetourDetach(&TrueCreateFontA, HookedCreateFontA); + DetourDetach(&TrueCreateFileW, HookedCreateFileW); + DetourDetach(&TrueReadFile, HookedReadFile); + DetourDetach(&TrueCloseHandle, HookedCloseHandle); + DetourDetach(&TrueGetFileSize, HookedGetFileSize); + DetourDetach(&TrueSetFilePointer, HookedSetFilePointer); + DetourDetach(&OriginalFindFirstFileExW, HookedFindFirstFileExW); + DetourDetach(&OriginalFindNextFileW, HookedFindNextFileW); + DetourDetach(&OriginalFindClose, HookedFindClose); DetourTransactionCommit(); } diff --git a/include/zconf.h b/include/zconf.h new file mode 100644 index 0000000..1f1cab2 --- /dev/null +++ b/include/zconf.h @@ -0,0 +1,545 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H +/* #undef Z_PREFIX */ +/* #undef Z_HAVE_UNISTD_H */ + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +# define Z_PREFIX_SET + +/* all linked symbols and init macros */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_bits z__tr_flush_bits +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define adler32_z z_adler32_z +# ifndef Z_SOLO +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# endif +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define crc32_combine_gen z_crc32_combine_gen +# define crc32_combine_gen64 z_crc32_combine_gen64 +# define crc32_combine_op z_crc32_combine_op +# define crc32_z z_crc32_z +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateGetDictionary z_deflateGetDictionary +# define deflateInit z_deflateInit +# define deflateInit2 z_deflateInit2 +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePending z_deflatePending +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateResetKeep z_deflateResetKeep +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# ifndef Z_SOLO +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzfread z_gzfread +# define gzfwrite z_gzfwrite +# define gzgetc z_gzgetc +# define gzgetc_ z_gzgetc_ +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# ifdef _WIN32 +# define gzopen_w z_gzopen_w +# endif +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzvprintf z_gzvprintf +# define gzwrite z_gzwrite +# endif +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit z_inflateBackInit +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCodesUsed z_inflateCodesUsed +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetDictionary z_inflateGetDictionary +# define inflateGetHeader z_inflateGetHeader +# define inflateInit z_inflateInit +# define inflateInit2 z_inflateInit2 +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateResetKeep z_inflateResetKeep +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflateValidate z_inflateValidate +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# ifndef Z_SOLO +# define uncompress z_uncompress +# define uncompress2 z_uncompress2 +# endif +# define zError z_zError +# ifndef Z_SOLO +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# endif +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# ifndef Z_SOLO +# define gzFile z_gzFile +# endif +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +#ifdef Z_SOLO +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif +#else +# define z_longlong long long +# if defined(NO_SIZE_T) + typedef unsigned NO_SIZE_T z_size_t; +# elif defined(STDC) +# include + typedef size_t z_size_t; +# else + typedef unsigned long z_size_t; +# endif +# undef z_longlong +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) +# include +# if (UINT_MAX == 0xffffffffUL) +# define Z_U4 unsigned +# elif (ULONG_MAX == 0xffffffffUL) +# define Z_U4 unsigned long +# elif (USHRT_MAX == 0xffffffffUL) +# define Z_U4 unsigned short +# endif +#endif + +#ifdef Z_U4 + typedef Z_U4 z_crc_t; +#else + typedef unsigned long z_crc_t; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_STDARG_H +#endif + +#ifdef STDC +# ifndef Z_SOLO +# include /* for off_t */ +# endif +#endif + +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +# include /* for va_list */ +# endif +#endif + +#ifdef _WIN32 +# ifndef Z_SOLO +# include /* for wchar_t */ +# endif +#endif + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#ifndef Z_HAVE_UNISTD_H +# ifdef __WATCOMC__ +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_HAVE_UNISTD_H +# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) +# define Z_HAVE_UNISTD_H +# endif +#endif +#ifndef Z_SOLO +# if defined(Z_HAVE_UNISTD_H) +//# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && !defined(Z_SOLO) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/include/zlib.h b/include/zlib.h new file mode 100644 index 0000000..8d4b932 --- /dev/null +++ b/include/zlib.h @@ -0,0 +1,1938 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.3.1, January 22nd, 2024 + + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.3.1" +#define ZLIB_VERNUM 0x1310 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 3 +#define ZLIB_VER_REVISION 1 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); +typedef void (*free_func)(voidpf opaque, voidpf address); + +struct internal_state; + +typedef struct z_stream_s { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ + + Bytef *next_out; /* next output byte will go here */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion(void); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit(z_streamp strm, int level); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. total_in, total_out, adler, and msg are initialized. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate(z_streamp strm, int flush); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more output + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six when the flush marker begins, in order to avoid + repeated flush markers upon calling deflate() again when avail_out == 0. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd(z_streamp strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit(z_streamp strm); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to Z_NULL, inflateInit updates + them to use default allocation functions. total_in, total_out, adler, and + msg are initialized. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate(z_streamp strm, int flush); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress was possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +ZEXTERN int ZEXPORT inflateEnd(z_streamp strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2(z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy); + + This is another version of deflateInit with more compression options. The + fields zalloc, zfree and opaque must be initialized before by the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, + z_streamp source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset(z_streamp strm); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. total_in, total_out, adler, and msg are initialized. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams(z_streamp strm, + int level, + int strategy); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +ZEXTERN int ZEXPORT deflateTune(z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound(z_streamp strm, + uLong sourceLen); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +ZEXTERN int ZEXPORT deflatePending(z_streamp strm, + unsigned *pending, + int *bits); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are Z_NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +ZEXTERN int ZEXPORT deflatePrime(z_streamp strm, + int bits, + int value); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, + gz_headerp head); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to the current operating system, with no + extra, name, or comment fields. The gzip header is returned to the default + state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2(z_streamp strm, + int windowBits); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary(z_streamp strm, + const Bytef *dictionary, + uInt dictLength); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateSync(z_streamp strm); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, + z_streamp source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset(z_streamp strm); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + total_in, total_out, adler, and msg are initialized. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2(z_streamp strm, + int windowBits); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime(z_streamp strm, + int bits, + int value); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark(z_streamp strm); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader(z_streamp strm, + gz_headerp head); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit(z_streamp strm, int windowBits, + unsigned char FAR *window); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func)(void FAR *, + z_const unsigned char FAR * FAR *); +typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); + +ZEXTERN int ZEXPORT inflateBack(z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags(void); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound(uLong sourceLen); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); + + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); +/* + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); +/* + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); +/* + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); +/* + Read and decompress up to len uncompressed bytes from file into buf. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, + gzFile file); +/* + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. If the library + defines size_t, then z_size_t is identical to size_t. If not, then z_size_t + is an unsigned integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a z_size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevertheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, resetting and retrying on end-of-file, when size is not 1. +*/ + +ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); +/* + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. +*/ + +ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, + z_size_t nitems, gzFile file); +/* + Compress and write nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. If + the library defines size_t, then z_size_t is identical to size_t. If not, + then z_size_t is an unsigned integer type that can contain a pointer. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a z_size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); +/* + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf(), + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); +/* + Compress and write the given null-terminated string s to file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); +/* + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc(gzFile file, int c); +/* + Compress and write c, converted to an unsigned char, into file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc(gzFile file); +/* + Read and decompress one byte from file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); +/* + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); +/* + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, + z_off_t offset, int whence); + + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind(gzFile file); +/* + Rewind file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); + + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); + + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof(gzFile file); +/* + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect(gzFile file); +/* + Return true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +ZEXTERN int ZEXPORT gzclose(gzFile file); +/* + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r(gzFile file); +ZEXTERN int ZEXPORT gzclose_w(gzFile file); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); +/* + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr(gzFile file); +/* + Clear the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* !Z_SOLO */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, + z_size_t len); +/* + Same as adler32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, + z_off_t len2); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +ZEXTERN uLong ZEXPORT crc32(uLong crc, const Bytef *buf, uInt len); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, + z_size_t len); +/* + Same as crc32(), but with a size_t length. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. len2 must be non-negative. +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); + + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). len2 must be non-negative. +*/ + +ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, + const char *version, int stream_size); +ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size); +ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size); +#ifdef Z_PREFIX_SET +# define z_deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define z_inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define z_inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#else +# define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +# define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +# define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) +#endif + +#ifndef Z_SOLO + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ +#ifdef Z_PREFIX_SET +# undef z_gzgetc +# define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#else +# define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) +#endif + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); +#endif + +#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) +# ifdef Z_PREFIX_SET +# define z_gzopen z_gzopen64 +# define z_gzseek z_gzseek64 +# define z_gztell z_gztell64 +# define z_gzoffset z_gzoffset64 +# define z_adler32_combine z_adler32_combine64 +# define z_crc32_combine z_crc32_combine64 +# define z_crc32_combine_gen z_crc32_combine_gen64 +# else +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# define crc32_combine_gen crc32_combine_gen64 +# endif +# ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); +#endif + +#else /* Z_SOLO */ + + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); + +#endif /* !Z_SOLO */ + +/* undocumented functions */ +ZEXTERN const char * ZEXPORT zError(int); +ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); +ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); +ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); +ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); +ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); +#if defined(_WIN32) && !defined(Z_SOLO) +ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, + const char *mode); +#endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +# ifndef Z_SOLO +ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, + const char *format, + va_list va); +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/lib/zlib.lib b/lib/zlib.lib new file mode 100644 index 0000000000000000000000000000000000000000..c0053ce936326df80cc9c9947306ea9f29e670fa GIT binary patch literal 195498 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

1)V`YA z#y;0RC+cXIEBZa|J@-e&pr5&i3vzn8AMI=@rj zJ5tq%Lu+0-JZsgN-2;;|h7N0Yu*c}fEmi;g`$K1JFPwV+?y@QK9>`64aL1`%26nt+ z{3V(9CBM7VS8{H*8nhsBtsxrafyeI`YQ6f22Ng=^gFAaC;)Y z&0n-}O{Mkr4_{xm`00zrWZa$X9v_u;;KMJj{PB&h#YI2NRex{ak+pI`TG;WigFnB; zzBTgG{NKm@Q1)W`imrt#_x31#dhf6n-$p)HKj!qUuim{f_xE2bBlonvclzSKqicV9 zu%PPibMCL)@?zGE&L^+7jvjd6)hjm5&4o9^lN&m2E$)+T+5Mgk!XOSoLbDZ$fH`=(s~Kt!Ft*-=5l<~ku4pc zd8Q$Ta*F!FH`)68$aP;g#I$A19rTUQ?*|Xs8)E3WvBgXaTf#iQ@l9L^2It4d7&>86 z9Zp)aCAlGnPC^#5lfLm;k~jXhhM4w@nSpQ0^Q*6akS{3w;1f3ewV3RDR9_Ynm+<0B zmHvuIDnw<_mrTt}azdBCRXwzP7fIzzRvDTtx*!lq#VnG)MeG^*fR}k9KF#z6)A*S$ zv0Ag9=?msy%J)tqP8*d|;w`4%c)v>L4YQcQIc7(r)+fSB~SJG5*TNzLKY z^0yvA=OxLZKcdD0FX9Aea|6u22AqEyIMWwQ%&%lwyp*7F#ikoSRJdEXdldOWiD`L{9n#yzkT1U~8)N<951Kk(6SL!B#hx;`t4f z{kJ!s(xsM5DaIJeh0|3)9d_!l^i^Go9@0}{jKNlSaP?>z{a*X_N?qzrDa9CrtxH&n z&j_I2d!qCQU22PzVvNDor7WeE%N)J^9$iX}E5jIrtsVwjyYD&EL6QXgQiZKRT{S3Ckx?Va@mpUM&7-O*2Uy}l1D!a7#@o=rZzLrvqG1$6FlcHI){-$Yl zy3{XHiZKRTv6>VJQ?Fe&^wMJv@pKF>V+^+FJQgs|Z(LTXOVNJelo(^M6$h@6qT^&s zk4M!*N-@S@D_)Z#$m3&fU#UwCkW!2>*h*k2YA;Gpgx#5J)9Nr)N-@S@D-l?|T&{|H zpVFm9ODV<}Y|(jML;@qo*m;)Wx>TN&VvNBSttoU{WhcMtqf5<`Qj9U!qSb+J>x~B| z-L6Y1Qi?GKTePInZT)THpe$YLNh!q`gRQ|VrS|z33%B&vrQVcMj4{|sG1&TjQnwd% zsm)S~F$P;hSc>KiO4qFGo~p-1`$S4H#$bzYn`x22%msJt)1|(XQj9U!;+s^w1|VA> z#lC=jV44$&bW%!*8(D#C0KV0v*`j`^OSPbjP9$+VDll@J16;9YBgIcX_WVn_RA(v0 z7(=<7ETx`PX5Q}|r%UygQj9T_E0v|x_9}gUUpHN9kd$JK!B(2V){$XH@6@F{Qi?GK zTP~KO6$Pc)hn6F-hFXU=NGZk`Y`KBe`{C#=8$Qyd@}(4G47P@|6s^iAjXZx}b_>nc zJSoK(gDrmWp|w|J_WSE}DZi9r3~PN99QDj^j2Pj;af_L*4k(rU?IBDyaym8bm3jzc zl*$0dVs1eqNDG$KzMxC}Dy0Zxl)45Sim$nE4set#c zM}T87)0@}E^eZGLPMlSkJ9*Z`V(--a!inNacw*rkifmDggZZ=POq?hW;!1ILVZp?? z#qxT2ZgGL6Bo3FG1%>L>JVj`b7xwJZuKviGTr_!hF|Isuc{oRzCiEOjr}O}Z^hgiPmjoGDs;|9) z$=51T1ELH}fs8XU1u}>!kny3AK}>;6422A03gp00$RMUxa9LL(i|U;dwd%C{CR(M) z`zSg3>cOWKP+K@b|lT?aJk*-PESTET<67ur(uaa?F@?_mMCX5M0((dPs0**LAd8< zMNSR$TA!L>ghU-`OVs>7Y0evK@;lqUwB{M#u{Mkq0z%F3yv}{8ncqrT|@XLYe*OpK? zFX9sl_cHjIz?_sgS~P^hQT*Rau{`;fZWtobpHR3vfLnx>K?}M?h(xQMP`DPrT@TFo zjtu+L{4D^cmt3^BY(yVjjm!jQrNlvfNW1gEe-)Tsbb}D7v3e=Su{2=TNL*w3@`0-Y zrVrgZL~0Dz4+r9bnM5}Wks7P#={U9mn4cuBvHYb#Ut26zJ#<45Nz)f_r-}Gf|8pdU zep719FK`}kIL*s{%&iczB_<>s0sSsYNEc4z-_&NKDz$-7MSzFI6nXCl}h!} z9XE)h@uAdM{b4FF4F~4>U|a}&USP_CaUuHOlM=&*@zq%SJ`dbKE})OfySIt@XgBTO zE})Ovw}X1YDl^zv{<;CzTVnsL{#;GeHyXG}7tlx3jZM%;&p`G!0e2a2KQ{qK`a00#n1ICj3%EX~ zLq~Al8W4n|MGO{R{}aDxA5^+c=Jur8HF*5=eDC-Lv+}3(<2S0tPbtZtHFbPi_T-s) z!}Dk574xxTL~zW{?LRfYX#DgAc(ZD1|J?qCQ*MFJ&ye<}Dd?eiPI;xtcRM|=6o0ex zbBhX#3#WPQ(bx5{(~^C5{sMY?DhCo(FeHWrr(f zlgBbjY`acx-nS7xDR6?gsYZdfs#$oq=>C(cYtKYjNWzC48{mIKZ>+<+!5d{4{wl&v z8}5W~HjY2Z4t*tXIq)Knt&nwF#cPoDEk*X@TyO>8EWuI86;lmYW|SbnFR&a)&PrOC zbRZ;8MO*n@;Ol;M%85!(vs2aQ@Z!C9yzlhCy+eGb|M0eFN9%>~xUp4~;!xcjxb4{G zTl#R+-9Rtu!&;WjUG+WmnYj3Mx2W&&3rFAp*XFvB>Y;{Sb_wbs%7j{kn3<8vE`FB;Qf9cZ%`kc$JFja-7kwg zaz-V&EpSZ`zSboCvarOS%G?c8V3Iyo-dS=mQJB#c_$v5KIB834xK6+s z>1XGAka8#^;5}dKim6iex>L5eZRuM)mXD+-%ifBrC9M^UWs~2MQd{&<#s2xd&tKyZIyg$w5{SeXeC4UIFE&^cc3qOk|()1)>f{N2)R>J9|A=7PUre@ z_zlja|;fBfwK?C}rc#>S{!6w1F+s`M8}ZwTo!kBac3B2awt zrQ9m&5{fS5#4a4vbXf(X=5({-$iRN`F_=_3njSE|=f-)ImSssjO0F!MXI4t0)bSTz zRh#B&MkOjnW3a27mZjukN6DrBQuxHzrg8K68Q{M;N1bnRQJ1?jk@%t_2(exF|)D!rQXX<&4dKHuy*)--wzc{2F{YImH z)Np4s+@;7)GJaW28K9z>qBkxaOv&D*IT$$uoWZk|6FgK7vKv0VGYDsIS91OwZx`~n zbNTZ%2VGk^naNiE5We6%6J({FfZw0RX-hqc9&;H6cUa06_cvyiQPF_CG}ma3E!MP8bXhB=i#;BSseQ^~~m-QtR= zRX%a2Y{vNAtc_oc-Z0DQl=DT05Yl5R0y;#?cCG7yp5tH5^O*nTz&Xr&lak`{$H21? zd(~UM&$68MnA0Na+6MNtByxSP=!Qw1Jn{S1rjfIriD=cI*f=}vP-h1*yXQ3K)a`(l zq4-!$i||dqtfo)!E#`=pFe0YCD?tt6qa#7}VrncXF>g!<6)&3r zOl>m!!e@w{;tav#PR;`QO#d~XCX(qik-#ROR8JER*7a=s1o4V`g78$-+bXW$b1lZT zII~Qwp=nRl+l!#Y>EbXbak_9&7!W&725{jMO9;5}jl>$>R0QbG<%z?XtisMkgnzw;^R{>0ahH+YsKb1 z4QE@NBzTsbP@}n&PN<;?gBImh_Dc{Gga^L`H3gJt_E{RQ1XLnER#TbA(@yi`^-0k` z_?#*WT@vA&?=qFN_9dH2nsd&TG>1UMK!d2fVBc^T`G!-Kl?--bJ&GR1i&1!p*9Z^s zL;oEQag23S4L(-WwfGigrJG^&NE@q8atT+qktgQOYJNrsWXGeJk+VxY_0EX;t$wpd zafaE}gn8<#GW^akg`6OxYlMe3J7jf zG|pCwrC)fEN%YEqbBUS~3|k=6pkp z11^l(DR7kp*Is7fbkknR^rAnu_MJJWI`{Kvqp?)Q25EH4$r_aG$<(rP+WriYV5sR{ z$I)dA#3<|NTYxdz);HKxf+fgyHnwb`oV0Kei4&zZ2p9Zmh@9~i_4CHj#EKJvr3x9w znhC4=`mIg`ez5GVrI+BbA{-T_)H+rS_S9!apz^^IYa5yuCe}Dp0^%fztEZqiNiudu z7OkAH0?0_&R}u>Y8I|GY49mWZlx=e_qv$tU^cdS3XT7I>o2P#Jie{da%%sxeilx2^ zVPYy%5!@gx%&{T~Q)I}@#3FBElA`HQwD=lOTkx^+<<#>aD6%DT^E9ZJ z@ljJKy$f*=CAI4A%T#tXc|eGg3W`d)jCtm6txetVu&x^%wY!aOY3ha&cZ=(C1P2W^ zsiuVnL6L^#%nNLfd%#f>t>cA+ph%*Ud1hM+lWl5ClMS|PacyYI)ArCLn#P5Y6ckC` z&phGg4;TN@aPfybZ>KonSV&L))I=*NAuTA9rnyw>2Q>6dtLRH6nq`HAph)5=<^}gq zdNQXb8nZ%5P$cyn^DZ===sBR8Xd)F_1Vvh?tu3ZdZjdDfdGqGv<&uMAUcprIlAMNn zYz@34bhCZ@(%IFU+SygcTKR$lJ|82XQ zyClwfVbk4LE?$v$_hqwt*w#FMbZGmwwLcA-`_E2;+pPNb_3$I}(!cBZ((+%D+P${t z@+WS1?cP3Z9=~-^-kiE^r?w8=+u?;{{xiGVz0q$;t5)%gwtm>^X64wto!5Vz|M6PY zRdMU#hlci_{#BUz`?kc0JsY1jZ&qFRQr7Q%tmBB&omE#y=X1W{Keyalt-2a^{l7ge?PkIyg&i0I%QFC{7!h8l_~ zh$aIA4uXoJWod$P5$^;uUhW4Eeb53T>(_gBw| zc;_co|HsevKmYvMKiLXC+IKMA_w0<3Z$BElwx{w+@m@#W)Y_V9L%QyGVc3y#ZB_hh z{W~q(@cF*^YIp~CY?GS)$BXOK_&t&F+vK;tJey+Pis)^-tb4m|*A9B+<;YX_Uh(K_ zli&Sl?Wcpr_shQjqnB6ysUlw8nmFm7haO8RRUS|a@c*@~iPQv9{TjNV&sUANu~9>d zqu2qUVctXcynTS9%}NadQQxn5Jhw5XC1a@Rq44ZI^vt=&7>bR}O5q`^lfQZaeX`kBE5=as zO+LfQ{shHl40Sp->ms`1w{gD@EvFfSBm;)Jc=EaZnjc~tW7;rgro?m%?YpBfhEm05 zrNITI;qHB3k8O;JWXue@;`h*J%g`>H!_$^AG z84E}9!l@iQA^LH|n-Ia!HW1Rw5oW1d0cRAc+Xcm@z8SZJQy`>TTS)Va+dcDCp4bLC z<957hL32(hvF(tkK6HT#XDOl*=)z9uAuV})FSa-m>EL^D5%J1t#F^ZPgJP>WA;p1_ zJl-zYcmv^_`7-Vy2qA9{oVH-vOnR8do#f1!KYuoB5gQ1Jyo2v4Pb8)o(cl1R8xhNA z&n#tBOBJJ~Gi|37+YU?cPDwaQjm8@hvB^-|E=c8vH}z>8D&fo-6fd<}fDT$hTp3NgkQY*DLY-2A3*EsK^?j4{}{ z!eDEcEA~cRYJiktjKS8G23t4%_Qq5CmN|!%VvNC74}-107X7wRmr{q|j4{}XW+{;) zIQZo+H{YU56-rx-G1%&9uvPK%(f4(!g;I(!23x&YifTQj{LS~ivR9Wv2*Q@$pp7-O(?mBH59?azIrOI1rL#u#i}%~F(x#U zitBW#1}ViDgRN^>it>xx^DD>xq;E&Diw+434JbGLHv+{GM{A=7-!#asOZAXaj4{~i z%Tmg)7)B?Lv~>l+AHNh!t{Y*AllZ0Gf@ zfcHr$#u#kT_(iw%=lk!*WCM+|$vq>b7-KlTc@TV?+V=CBlp+i^y7(fC~fR_pS?f`;eL_?VT@8kSc+;8xjXLtK1Y}8Mhy@gVT@9V;ONHz z&$@FVs=I1S-Qq|Xqf`=0QR_Lz47=#;k2l<`fDoL?BXvXbgPeqwJP?vjv zgz$f`^M?nI*pN_IB(^nZdk)w`+mRsdG*9d)!uVG6mA9HV5A-!(ap&*px5I=-`}z(O zIsDgT)q71^J`HF9^7yYuhS-lmJ4`f|*cD=6>H9iNDB9Vfu{3kyIYTohZ#8dh z#_&%ld8>PirvgnpPu}YQen`;$#jWnGW}ApepnS{|j}W>Fd9Ul>CkowP-0I%Otj^=x z|Hc-QR98w`MrNjS>?kJ=3RNfVu!&?|q1cQ<^LF|s4xn?!W@n~n(eb8@Hk`;x5@5qg z>c|vVT2|`lOjica!-&~EY#qV$p4_pb8A;7aab-IlsTo<#?J=QkBJWl*6=7Qe~n0qCzsrXI? z?h#;4H-l>p+(lqo$x&ld`Uuw%m|mBG>kCX$Gq?%Rmj=v364z9GdjaQ{k(H z$7jGiN(l~!9ywt8O#*+1#1M{Lpme4oLsxn-_j7@8Q{X=VxYs1Msd$tC_Z~2Pl1*>mslFJFwUfp9z2#`roMZCd-O8&ZM{r=yMQ~`j6P~#PF<$H z^T37B32m=$p&5OYer1=b?@r+EZ$=-* z_qEH^w-vben$bt$J9?S=&Hxug9TD86(l1(K1o9H)54gl;^ikDNcTY8^Zyt2r-i$tq z@58`sG~)u4zdgWwYQ~w$AGI&ED=L`g?clU@381eRF#XLqlRgSxHZYBLG6m2_JDKik zMjwUm1z@(CaRKyw3d~V6&hNonjh}^P8~q&D4-<~csjU$%rO{3ynm})L893_qx-`N? zHquAw-?b60@y?@A;I0US^LyL{#1e&$%DjV$-UDC&`=9LCSp}8O|HY0S?C$w*Y}io` ze&dr24twjbaxpFnstQcmedvCSPWs~diGkqD0=!`+E2Mc%9Ww>c2f4yTgsZwekE0$WVh)Rmp za~k?^woDI_ugbAe6k^rG?Q93+RscHUF8UaSnAXFmh&?S>-b#l6(m^FO@s^5Tu;qSS z)0p}M*P~2*jq7(z(X+>3rf8|%9kr%SMp*qQ506Vv_!cLrC_f?@)0IDX0pzPFPj7t= zVRgU3=e!N#VX!ICDe~YPAJ)S8@?+~#`dXsVAo%hZ;Wi4tDfr=lo{$RcE_fJfTvZ)$ zwG4}2YPY`=GA!wiFz>N=U)rSl`MC8~f8sqidSRjKVf*F^Sio|;yI0Xamu*kOH+5;e zPOm;41RZ!)KMVxbv-$*as#<+qUD_08^a4Th^<6+v6|2YUyD2orq&1K!gt2eVu(}#{ zB3za8kt#}B6m5X$1+U?}9=EMCsUXE(*%k~b;k|It(+%sAapYaXZkZg|WRr=M!ph_N zmac}n^u(AOC`ZRyrN1vNn$v3!ERuY8lrwj`?5dGgXwi0Y)OT~PiLUR2vtiVnueu4V zYS9%}6AHLdp9xBY1MUT9c; zjc;~$h-2BRXFsS zT!@V-Ae7M3Q7Qx|o-SIMkLCGp{n#JJlv)w;9@u9<_F+UVN4_*{&w|$AY+r#(uE2Eq zdV9igpX2luIO~IP&4*2tq=Hha%#q$DdR+#LJg{247G$K;_v{)dKRy>(iNiu?<6rSw zFfQMPH|eZ?K0)C&zq{~Yx@i#}qVYnB3Trt8c13->1Jw8U1zVoS^%neWd{WtDrZSKs z^duQ{Y(*YsFs~=5bf)@%8p+gfP^nC1Xw)5`ghaK*I|ix< zIGg2PpbD5e0ctu^r$H4mbq>^2rv3nx&lH3#)0hedHHE1#P`5G_0V zu_x*fwQBJR4P0>DErp(5^}!U8$>z`2Q>yiu>-_a@Ua|h?BfL7&oXxB4rqw2rOqZ(U`@LxXcLeF zXL9K$2ChVNrHqSOd7gSwcf`u`;(W?kU^@|X+Bg-C%@o+VOk1yT*M)XgRF1+8pG{YF zTdBK^%eJ_rKFk%jI1(q>l_vb;>o4?qW?`R=)l-O47U{Bmv}m$ob19#phjGR2GjuUX z2YbaC1erP!U!2P~JIB|bO0uCN0UIMWY}vBa`DUY)NsILH7P{lLBw5+8_;z8|UilI+ zY)c~TYn}n+7YQ1DVRb&|f_fSzb#CsZvdH-2sHubb+0@j{&gTFH4hn~1whV(>;<_oV zT*=sBW*=Fn?2FswvgTrAM=o}mo%gk(0YxjE-;1=vh-^uTj7xo}S}esrO>GY?SA}N* z7Da#tCZgu|ga*N*gK1@JP`3kRvH^+a!LI8aqFC6S`;;BE=2~-vx4m@0-k=hf%@L_q zL4s0~WaLmT^fPO~*>5;_FM>ACFy6KUEr|ms=(>m!l?sZoiZEDy#WCH*tnrV&2qSC-X6G2}qA%?pFsfW!~XQ zPZ|GT9U*77eK|+S7=MDjFv8WQ{D{wR)CMfa~5=2oPRToJ2YIy3qAXL2+N8P?|LFgr&lme;? zq_+y5#$6D-R5<=mWM8r(D2m5A=9$;|&jnX?H-ZppBPf!3gn6RGU?&3hO?1Fs26Z42EJZ` zNP--tvutIFw5+l(Q{TJiGRp;d3|t(kEit*@)!&w@|3|dFCh@D+ z?*4Rf)%9<@dhDSmk{us^op|+>`^UcO`}mFA#}EJh%J(~L2k&+LHY>R9i&Ll9-8<%+ z`L}NgAKTPIKzj`kX-Zjw;Xe^NI^4ExuQ{a-nrYMXoW*H<2B z82VNEnd*y==RZF!J7MnF?D#hq?VI$#kb^x=jy$zycB|4KyG*_AnG4Rs5gWRyn>5t( ztkg{vE9xg^ghZCVxV`=NJOARX?mISr#s0ikfBsyxH@CX|=&Np+JAKU~fA80BMyt+S zyS#qmgJ)7Usq*crcg<-?N!rtW%IU?w-*f%`+rPf2p#6KZ3$7fs^VvVvwOBsyKv(gSN`}W{0$3t(I&iqLApR{mETI55~?_D=^ z#A6eG{kr1N%x^xJ+xgcI)J-1q2DN&;;mzA0wmdxK^puIp-NUBk4Cq|&LnpOd{a@R} zK{byWwM(5ZMXeq^0o^pP@RUF|-ozpLEi5{{|HU(nG30BrQtj#nYDq(NQe#XgW2mj9 z@bup}`SHdW3a!lwVRqAohJ4!?(~>dNf03RG7oJ_;7=wvp=vj#?#cQ+o&B2W^w9r6b zJeD%HCm#PfWPWFKQJZSBI&q~2so*2!-NqPtV{NliKS$E#RHcfGzG-78k);(}?r1 zfg@rucn~qwEk6_s!Rg=^3&H8c975Bx9=SFWqo2P;+g^nAR|EvLT%-?{oyoY1%`#Z& zrX`}-V&i{q7L^v>W`fp1I4WbzNmM!1l8CJ+90lA_-C@qa1PP)Ri8(5S&!7@gs%omU z%t=%^9aPSM>!luQC4^=bL$!)ILk5ECfcBMJS_@(^gsjtisKyx(56%{rkWvE%;I7)h zAw4vDA}J9VHLRb{H=3ra4(glt&h6U1H!POT?(+Od^6wMisV~k-jHuYLIE48lVJ{a}s zoX(o9F9nl(Hsj)XOcMFo@_p|M(xoVE$T7xX>k4pnTeMJL-y-n`%ixVEVGQx&EhO4P zeLBrWmr~C#V~oL854J_UDmmJK&`yh2H>5f_#u#ixgR7_EunTkc>r#EC6k`mwda{&i zYxdUKEA(aXcmc_dF$P<`SSo_9_{9y_zEqc@FCCF%jKNlKaP^Z&;vaZ_ur4)CN-@S@ zD~6?1ThCp&{sCReBc&K)uyqwnQQ4pn)_wV}_jM_slwyp**3|}EpCA3lYr2%W5r#1a zTi39ZnufF?tG$+AuS;8uG1!VV*rJoPbg617#TbLFKAIE=-t3@nKAE?F$P05Qw^U@e&utn{?ZmZ2N-@m6z&5*Vj zW3WYii#VByY;78L*F*Ytr-f3AF$P=I{pq$&e=w=HF11=pF~(qv`X9Y6&ma1?4Z75W zQi?GKThx>2w%WXXY?Lnbyp&>$!4~ynqV1*98`abPs4m5CnZad@!4~y(x~<}%jo;}~ zyQMA07;I60sK={z*1Yd^sV}4yV+^)v46NIl8r&vRm#UXij4{|sW+}CeGRBMEfRba3 z!PYQvbz7mYO#ei;)tV9rjxkJK365H;jGJ7B!yl*TG729wdSyKVD2-YsN;YAPQa7-a zsf&k?vql4F-oO?W3$SJ1~fU<)+Q;H!aV;CP!4eP zczx?!^tLWlC#48uw3W(I^t4NEPD#Wqy3|)viZIeX4e_Ld9=}ylY2cy`s=-u2mIz2( z>hunEhfuTU4ADN7qG@ypkQ8a^2%v=p;Inc3 zZTK;S4n7;lAE7h;cZb~!bY`VxWoC|Xri_S5%P7}2?hHv!9g{UCW7HV%oui8jad-{< z3vn}6!(7HeIq_*@a>k@OTxltq)WGb~qeqTRbBs!%193F=U}xs2ob=4GWDo(-FDa;J znR9W9PwKStBJA>!$H_zs*W50jAp;X7l6Lt7^DdwF&@8I$X`o#`o3xfk5>4##`KJjN zXqOK?*ObHFTKvdStFII!{e!l<0dQf^F z9l~GttX03nNI?^utY{R8C}Jj!o@!}!GFW@d(Eb(YqFbL``OaT{cf9jb*}{YHWcPn< zwwdym@^oY9_ou}Sp4<${p|v4jMR%rmdMZaPft2^gevq&>Ycy-{zeM3i-)gB+3oX|T zN)SgZ$&%h&ok&O=FyMN|Qk}S)>qPi0i={@Ezd&{3bVvV?fNr8r^zLNDah))&;64G! zo4`HWSzxIQq*!uN{O2{v=V2s7C?fq-cY&klqCh)^z5}i^GUAV(0!Jwu2sagvZEJdA zl^;D&!qNP5Al!5WXek~azoN$kIGQgAgxiGl>M)2Q+9eP!8AV_h2J|)>GQ-hKR3KbG z=o=w13~T~d2mTxkq!VaZ3`f}(NS_aOhXb>dhO}_>)EWp!Q8))oUmCK)HKnf(9)p3o zK!a2`DyM<;dBDGlhNONj5bi4Idla~LQv|RnyR^D;H!w3&1+J-hoPqZvz}!m%NjMvR zf$U}@U0w#}w{(Uz8IJ;Z_skF&^%_Xucz9M^25u2>pI!!z<_pJ+L_9KuReE9wWcN)( z@M~c1A1!cHj{@NyhrTnw+@B+GP32oTyte_t4nC4jzB zz}#rYnZk#z$l?a(ZZj@`z88VnY{r@NQTiPO=36r^fWDwf7_;I>PK!qXeSIZHAe&CV zVZgbX(MR2GF)*vlxB%gM8kmh{T!8TH0p<%cE`Yvszy#kcV$oE5sa@(E`YwTfcepkGwGxFhGA~S-!;`8ql-^YP@!HhG-m-1sLFkhH) z0rZ^%COA*T;!^SL1pT$ zALZ|^e3X0q$Z5C$;X9v?=jdq+({ZNoQF)F5W{?>dK;L*^rkZgkeH6Z>5+f`(T|d?W z_joh%Km3}T@CYW(1eN>*yB!(5@(p3K5 z1KgvRp>OMD>N^PBk;~9`@iO&wEx?I__>t4nB|vboDf zC!5hnk8 z7*>c&Q|Y$?xVz2zOz#x(gVE-i^wESnrhfnbf2UAb#NSW-!CiA2=v_RME6~{pQT~ltz!l$HnI?j-G}SFGf!*n;q>a#JRH378X_0 z*z`Xb6M|tpDJVQ>sY;}_5P+sVX<=owCPny2ZG#gn8K7mKxOI{B z;p`RtKFErDDqZX*;YwA@YAL~$CatZOMH;n6qaFs;j(uOysI3~cOQSy5sAC%Cn-CM3 zJCTmpqMdrQ(H0x5ol2(DTm8Eu83(vxqjEO(>cuPPo%W1f*|?9zS!4JNh0~WEQ|frP zp#d97U17evV^%=vTE!dLnYLQC@>XA4bIyh>rr6HC>OsWWsl2%!h`4>uxHl_6;9xB5 zG!09u3XXRq*V$7~B%iX6Jmp9}S>C(yjHi{iA=q9y6>{}q^xY3SgOH%fC+w9j(D3#| zrd36RB%kzzIo<}xQg1`3(v`pSxpeC0S|ux%zT%J;={+7?^CJ#d8e|1aFl=i&Sn=VD zPr*3zv0w#(r4ZvRGa7b72CQr)Ia8Sru@5QbEa}SpC}+~#Sft3@*!0Su+yh+7#OO?A zY-GCfK2C0AP^R^cNSAe4bh>qZ_w+sx=rcE#PP9tL*HF@<({XrM8j{JGe8yFxAux0>}Cc=*%-3|_Or1k9Xm3S)o~?Z_KIy_ zDY?$%AIo}UFKmue*-_^WM%D&_?@}T&(KfRI-c zRwjW$|3&Roa-&4;jN1n}NAhP5`^eAYL>%_nGj=5JD({Zhx1m(Wrq%~z_wppf*t-Y` zGd6k8!mQ*y%1KmJ^6sd5M40NKEYzru6kaZ#;@mVuOB7y?11GKH?BQPApAnWAN-f}-!3(?~GbG7KeC@MdY$pEYU@@?H3D0VO2nqU9Af zmVlbUT1+3_F`PT-s(PIYpOe16bJ0~rUz<4Os_F-p#qkccgJ^#g@8h@~9)e(%_t6?5 zKW0m`7xs$DFbE~|J(~v+9`8AuebxOCRFoCCx~i5S$~Qu@TbkW_A2zg?pp50GE4!S&tkP8bmf+OlRA2Bopwg949D3^Ny$cHR?OU+v zJF66ANwL!xOdo}a#mTc|#-W6+JWipF+mT$eu$>xWpLdNG4*rya!}}Y8xD7x>Io$~n zUU3|I`n|_MrrWoK7CYnk*ldS=%Rc9tU~6%@ZKvWTU_*5=+E5?U2#^q=R#y6&e4J|{ ztPSktuy3xxH-=&n4oh)Eg|`|>wv{^1VrOzS>{OSB+c)3M-t`f#nq#4S2Y<+=D+fsg z3z1Re&mj~^!anDN_%?*YzJ5nsjgL9W$_p@JUwsd*oE4QIsvHd>6&kp5QbwSnbL*3v zo!NW8qbf7VY2O@-JSi2~cHju*hBKj>@`n=J=}Y5WNhzjG$wdZamDsniI^uXaksCZu z%KFdw(NHZL%;S3y2x*agklQ&<+iqdX>En>dZ|bBY7;PO@4l5Z19f=YngF&2hrRMlD zD03)wBn-}trjjIcLgc1%O-$1n(xex1QDha;dfnSF;Gfo%z6}ah21i3EN@F^m^Y|o# zDsaV##i4WxW9NDsj>W|B@ko?4-b0Y1=RB{K+lVI z(WTrN?NUag=iRAwnbu|Kd6!4y6BON@eIU?h0r$Ka=y@{$wmFmXqr`ckoa9`0Wkq&X zaeI1v5IzegvxQg7a+ym-pGAF)!+RmvldW**5Rov7NN$cA6USR9gb1~0??g<{>WRp3 zEMyQI_6Oc`R5@dU>c=^go~6p-9-%1>bt*@)ZTQd2So!an}ycl|Bb14HEIQ# zE1ISbwmb$(G|bhYMC1AgD4}^Ys;j_F10@>QCpF$18t+mKE?Qcg1y5BDEp4`FeG`7l zt{M)GNo_9$+^KwsI$t(LRB(JlBe$fP zs*UC~yEmF#QMtLv%>+;Btn85uuG78+AIXp{t`Chbx1s0-6>cSc%F_sd&wDpr-&})h zI=;3sMKnX@6BIjj%W=E=QM;VHYhjv0*{{Y-G)XvK+B7%gEsg;Sa;)6Bl6Sy@lcG}R6Z>~v2 zE1w9xO|sGY57&G$HaXQ4IEMQff_>QHuM_pYX%b`8_8c?F8 zAFNUB(Kw10{2EZA1s@7Z=sT+Up3;1eXzlxHt$n|)g{mbDl+cobVKrtOVx7uSd=Cgq zMeP+gV0y~sT^x@XBnUDQWGs=2BbGnV*o|(I!t9mpKw!$D%JHf9-0+2wu5H#87Br$k z(JuS5JIdO6f4dDIwEFE)M8sbCJ%)e|?;kDfs}F;6dGCnCCz$w4oq4hLikHCi-VtVT zhr7HZVDB;9uUryFqWCzd_YX`#tYJtLq~_oQikSY$p*fIA+4u%sw7udkq_2{jl5hqe zI!s9_k97}GKLnSwFv>HfE-i&V&XiD157#K&kftK;%Ese(G?n-i`fwL@$w>>tJpH`q zgB@F8&w`F(ufsmJ+V*kWKFoT=P*8Bc3(t5v?g*hfPkSXTY&ZwB8)WSjW00#Zr3E#V zF5k%Lt@J=!zs7s+T6<*zypqcMdLru5!fu2Aar%U&lI5!TCSv7rno$znND!Xcm!Upy z1O$)hOXIxfLY75rO~LK9d|c{#dLp*2pu4B(uKm_(qK^1!BU?lKWWx?$F2;siMrPyTNAyEx?G0(MJVBJO`xpXj@r}$z zj>&{!4sy|6nTERKT@sdLugpSOFbPPNJAh#l12%TinGp-)2`G^#S!m1`?*7L4D0&wildQdKL;ne>+Tib1O@Gf2ks*2 zE{yMp3J%)uNE%>&pgL%uh-L>=5sGGf!wz(*k;o$Z=9J(y!QlbeEdsMc0<%MjofZ2( zO@hXuiGU)?D+;B|D_2r!q`N;t8byJ2tO*Va5Zo>l09jr!C?oNt(qV2IMMf%Pv(+Nz zD^ElUrz7K0YrW^v?UlcYLJ&_@>=j3Ghhn=Z${DvL(W#WjDzl@~mA$C?HzdEmV5vjd zYdAul%)}j6auYF27D=;Ywj6cpFD)L?z*l`yeGrbW>B&16bVNYX<90eQ4{FO5IFx$p z>_oMxav}*a0JT?+Mx)`3yP)iad8cy5nS5d4da?ye4rMnPBTMN@9mh*euXJ18W!Mu* zkco)aqf}vyWfQIx5N&yOoQd7LvnVc5o8LB2GB2gnFQ9~nPzeuPt;5vKnd3t2q zOQY;8#4Rn}rKCjDU;q!sXbya7#H1=f0hgIv@v-Or%djH?Pn{tJezGC(@rJBq&Ml2!qbVTo__>acC_}2AHjDODAe!Z z`^lJjM581gp6e48FFoO)8S`WIrl%bpgU72He3vzhwAfGuKX5d3s8)7WrCh`(D;MHp z(%he)twD>17YQ$-P4oU{^(=BGf8(cQ5)BgE<1uPAygmTe<{74Bx$%iZOz1T1F7^#_ zq5Qa!CM9?d8f~iE5D&C8l=@94JU2ypUW{p+J!2cQsF5=XwrdXiu7OT zh}E>=gjn9jK^;LE zZjJyZ#+s9n-`nvEw$Q$8T5KL{c?6X3rMaC6%zIQD#r}w~tKdz077C{*=r4NCaV(s&PPy!{&QpBnEflQ<)y3`$II?*%oBc_%>4U@9V9rIJC36yh&wI_V>w`yI-c>BB<4y=Z=~mL(^>s*tya6c-oU zdsF~LGYVE$Ri+hvLq)ac6cF)*=-h#Q1fFOPPhn%ZC}mtE=V`qe%lU*4PR585))RNoVsXX zOYb&n5G@{?L-``LDj2ivzw7u=fXxzu+J|6cexKB9+Mh?A1u$%%L&q8BU8g4>AElw=RhKH(iB!*&m zZ@cRlr2$?tI(Qb=uXIIti#ClYhUq~jqY6*VjC`~yf z{ut%LXyq&e@F+fs9?DYy$tOsNP?M>E$jLEqItj0Y>bGbxfu8)fOkW5++vj8}2$tQ+ z-y6@HI@vFoaU<#|jy=i73^AqF^Asa7+d+dOkW@|Y<9LokHAPLP7Ri+q?zux5A6Atr zW;#q&w6*vAZSJs@=Xn<3CcOVg3L(dpTb#;Wq}Hk2PmPkJDmXm3)}HY>HG|!8vPzUo z8IQTnTD-&0wBggu`!f~sFian+4)XP&#wA{SmE2HXo`W(`N>Xy^#i%@z#HCcktROq| zk^n{vvC;suItu!Uvs{7FQEFBs4zO3!D_ZZ{F>3&uWUr*-lPOCvp+c`IC|x>$h4(NP+2LcAb42HO7yhSm}!aL^9_Haw$`5hBR&I;(s0t-aMFJFhX}~o zuj|`*8|=$lI`~C__ZRri!Ge{lbPTh??5qC*3_fs%(6(v#2HE2*Zui&}^RnUx|MD~IwKwSkiwa^qe2&^0v~=|CaCvC2nI zUuoZTF zTbIE@bckbw7Y}i24Oxm?uX<6N>T9;*36I8m;#C$&&IWiAe!-R%xZcdvbtpvHOickL zMm9xM)|iKRM6N`WJKbr23(G9G*YU4oMh@W<((HuI` z$Q=_!Cs9N@=v<>{2PSLfT;_7heNns11xdBLgh;g=oJ=>=4vq)m*AAL$xN$D?YSxe! zi&FoNDD|hj7g1K*fR8tl_SG#wWLMFguO;~<$_5-}Bc7{V1z0zNC-~}2#kn&qGs(F( z%$?$0l5){KbQ@JMwaf6HyJ)X?2Mn4O^>h#~*W&m^r;TTw-Qhg5c>F0~#I#HDPJ6{F z+~GVWyx5>6LMR+b38-aOzvru7hG(c@fu5m!+ez5>CKV}H!Cr(HZzyTe+ z*XP|NNax;QpLeTDW5o=$O+JouLUnx$(aBLWMlCy@``y&MFO9*0HYhw(YySka7%o#k zG!nmH%OE7)G^Qqjn#EK$WkA)^L~6}XihI8g5{0U` zsP54r3VwC(l4FoQz}BU?(2O9x+~^+9_{zKc z$|GF9@@P&#m$HP?4YPiIY5v`}Ft&2{;udEQ`NsD3{uZ>A8vJcZxZto3-^eiZCJEIE zAIqte`Uw9!Um8zIk4&M`AQ~ZMa%{rK7;>T#*)TOesR3&xu$CwATm+V0Q590psp8bN zeN1&}pI=?tC+ZSbP1v_&?+f-RvNmP!3vv10Tnh#2ECvlF#9W52yp*a^yicL(R_A>h zS4xpO?;1%_4*Cs#CfB|T5AopqAt>?q{WYjt@C&xIMyiUM)(w=Xk;eQy1f0yzy@I6t ztR+&-&&_m0`N;!y{ek9^`MDB83Dq)3ae$UD4Oxkkz)%;^W-N(CHu~rpWF#8;kO7@T#u7ufuyW$X>A#98hT7@qz?zmmbHxcRLjlyl%S} zH#9=$F&)1o%V%sG%t7M~CYNSRKBp)AK>fFmuNJL ze-+{%y@ib{r|I5ur^|NCsoW8U5k$6fjc;L?%Xb~yQg{UtuU%V50hAB=PO+M@>b8sN zRks8cuSIRjkxTFBML(^dvu}>DrB_X+)m`eku3fYeK&${z*W1Ze0NUER4lXP%@a}Bz zyv$>vbrj+{UXMWa#1tg22Nm2ZmXwJl0^HGJ{h041N>BWwdPw7?Nn&AapemQ`yM`V< za3b3sVf0=x-{~vwEBZM;GDT}N9aH&!H&lx9MX%FE?YkaS0rS& zhKrVar0j0oH_)?5l7BbzmQ|m!sX^c8_iWOZ3Zr*X-ylzDwl4+6U+w9jf27c#BJ?N8 zV(Z3OKg<)?ba6HGtv1q#fLm&v%EuJwSwd-nP>Q8J+()`|DbQp51HIiZ(6z=uUrpV- zf-#|QCAD^xEB9>z;q&f*g zVu_@^auN!qwgf?2pn|gyjSEyRxkzsr7U?agMS9EeVyVG@kzSock$sxBNN*Vy=|P~+ za`Pg+Qq2ACK_^JB&-r~hoxq9y2g!;wMiIven~o`yYiVKkmq;?PECcVxCk76`SW_dG zX85m73A~)bnN%8u6?!`zRT)9YmmpD)SG+)Dl%^eP^iE{k%JD4CD#Vf(J~i@^YyZ5w zP~&Q-GDPmP8Hw8I)Ld(Gq1sjB#k5R6Kc;gz)`4C^41W4sDCzT@6a`&|~o0 zWgZ)$C{A)!JwlBU&79gS5lki z7@CRG#O@SSP-fM*AkWgwl{I7?v#m~io?sNFVpFXi2hLu#Dm#XTdxqc^T+ek?sX;?W z1$nNiO0^9gW%Kl?N(~-5D%jJxDz(MXQ7tfO;N20z5-l>5_m^#U#ML;fR*+^98>eqI z2R6AH%i{!z7q?YUQG75VfK|@?Y;!N=wPVFGOeFCjSos8R%dN_4Vq`6xEw^1UJvZOUq1vdlsvWwDmF&%N9w z*lL_UTm9`gZA=--E4$R-ad9eT)(%(>fJv zc&B3b%yR6WfqdhhJOX@SYRa2RN@!)JAPcQkm8Km^+z_CX?rn~CP|whLI$O>x2U!|bXX zXmgLff~HB7bzGg4I=Rr&hN;j_9CECbC9h27bh^?##%aSsUuIx22F^f4^Y9vc69LKK#Uw|5q>+olJQ@J??|Y|RsdRpk7?H>G}h#G9Qqq4Ofu`^&U9r*lfzD4bBrN~ z*ya&%*oo!+GVBez9X>mzeX&--Ru+sG>JK|s{uY8*m$!C_jXd_sUdTX2YzkU3Dfy%F zLWN&p+xP``^4{`m;w~zCw^Fm2e9k`doY;?5mmtoctO_3D^U`EueZQ(Z8MCXrcieAr zC*@t8J;Nkn-A-_N;-5slHJqV0Aj~f-Pw%;bMsD(I~&-E1vvm!s4V> z1?NR2&5yNb%#X#sJgmmMDcXgWg~~k^*1WI$LsW5YUGk!>^Sbw$7uAP$_Q9Wa=ZWV% zG4X&3$`eL;wOtVyQRPNxfh3h-{PIn4;9bxmWgI=5J0@W^RB@CfG!*-WAzM$ostvBY-5_szQwsmKAB^ZYmay^C#Ia^B2rFqxqRFC(R@3#Z9cA$zU@@L13ek| zmXz`o3pFx%wKOd#k}?gHc-C&JIdCdI9xNy)oyvXB0gjzbu7XFNCQ7MsDsR!y7cYvH zaZYF44on&4I966u0UNE%%g?m^CLg2gs_vq8!kLUUx$a~vDCwJ=ZXbChyJ|I+8HaMd z=9eHx@{^mO3=3<|rz;Oq%}Y-{57c?8DVccZhS$)Uw*9Vx4^k5Q;!SZ45Gjf7whi`5 zdhoYz4ok$G*Go*gtcjyAte{;cJbmTe5oF(tfkZ=fVwmSfkU@gX0%;Ru3dmqVUJtT` zAg=`(BFG*fLj~CZWEe&lVd56Ui|Vqc9C6iEYbZJ{JS)T}f3UoFy6;J9^^`-7rjiqehkwbeMx7(qjo zu59qM6YmW%`$iL_TufX_+qgQP1K_<>(c+zGB7c$nVjAWyF`H%eL@HU?@W3lt_Ni}= zDK1Z2Ba^1FtZ_=6bqU_fp>|QkFtF4NjYb-Y>Q3F2cp_a2Y65<8qTPu)mGC81Cq$0B z3GG!p8vb$IQP{Vjdx)!cB=0M>r`Bpc#n+Icjd7!@I-sXWvDmka!j`@97wubW1bi36 zeL)UyO@jwZRO#iq6^CSpr3P0Al_Csq%f&yw(whcxR-vH6aKD&&Jx7IGMq$Bo`nRp{ z6@+k0@&ufJfs+==sT!g{3%TwZ6%9&gAXIx4A=L%4bq74@jKOexCMp=8i)w{W27rbw z%m2t0*-3<;>H^uSl(x|1nsigFghYf!MS>FXAiWct(XB|`_y?z^4`L+s8Z8LDq?5kQ zs=7d7rkAHUuQCi<_y-1;+VX?q3GG%z@P7_|A_oOUmL6hW&+cKC?x$N>?B9l4!rw#g zO%S=KN_WttDIbM2<)e@$)M5No7s$>N@TA6x6IrNAQd|X|;wmUgUm-~-dS9$M;ZHFV6xsMI zetN7)f}9Z}&=hN-mvqv1U{x1L?{;`1)*(Tbkb$BtpoU6y^FWB$3W`Ef!#qB<6lc1U zQzgh(;3y1&qL>Q_LcNWj>H_JmgQp%#RWHR-x360edPyhAsV09l_Q)q?Jq&rg@np7xlkSDh=%=Mkdf8O-v#GQZ;U=B*O?uS@O7kq%>wmuaG8K;h)K-fUCMe1QT3;+n zfLpYmss#B89K}~ql(IsCP}Jh7E|Bh<46#)8QY>}*x&@(^be>U_YDlBZts<5&VU`&5 zaQ3oRCt6mAmWJf;swYc~pEQMB#8^-irvecw>VLm&VQFzt#9EaioWN3C1x0x)qzH9| zUmgg53Z0-x|4c)yRlP=xK+{#|C7pC$gX#k5oiAeDJ;Ktxu(hT81pFV=%F=yc)QL_< zI_zs#9a&1!bee>xz!1x2CrT$UC(>p^wxKnN{@A}vdVmOc@dKBrq-uJ|^>(iZhF zVqn<5kZL?P$k8o*VPAE5AcPh{k(QN0%QX>}Yw$GI!`;HtxiG?FpU}z@K0f3Ko*?5% zn!e|+x_l5qi=ar$YN5riFQl5Gx@jPUgrG>GN=S?hvy7a8ku~~X`yiB~fvq?NpH@Zj ze>#3bT2LfSJv`d~X7b^2zfc!wS_DN}9uZooWk=77{+MmQ1|QWGfe^L@MN+iN61M4i zps*!U3L%%F9;Axl{|rr1P$c;$mK0-a(Tl4RI4<3Nf3(W#8oH!sgMbZq+b%c zB}CP0#OM}8NJuC3uBr>9_jM85s8*IJ#5M}CjY2*d%R9ak50vUkK!`LG6oqaJYgusS zrQdIKeN|WXX6nK3x^;fc`gqmOPain)&zO0?^xB*rSy$9$-k+XZyZp079p`+uVBDV` zf6X3$!#&QnOI{f|`HownozGqQ@7pf+Df#i?vB^1=2W-#2oO|`QGh2Qhf5i2HwRiNi z?SE8m{Py*(hhxLaLoXh;FFsy;^MeDA@BGK^w{Ji2O6N`gI=27ZudUZQA1$-oam6Ex zE+!wo^PX!8Kj?Dv=`riuJoxy|->0Pg{os%nci3;euwlT;gm=z8x9!B?KP~!j_t0nG zv(A3~;IG5h-+wUo_}dqY*Z%O+%3U2l zQ#RdD^2+SO$A8=fO4)QpM*9mlZkUr8d21 zR&M>I#pKLqlKOn+-2RteO26z9RT{p&Z}O)HRz22pPmk-a-u%-~g9mr$n$x*|{EoaU ze!Vf|nbpsZT^)0DJNB7de;@YH_m-6(&OY+ULpg2MRd3k5<n|J;AWkS}X`R`T* z&nRzo$DP+^eX=uq!!3&*|J$;czdqh^$e@RNcK7`I`LpldyJGsH_0<G3!lEw z{;N(;ZMeJZ;ZwOk#qRm`-R+}`hNd}RydrjG$dg+$_rIXxZSIy8H@x*~|C!ESU!*_o ze6_aX%S9E>+_K=N+n-%|-{jKA7A&4xwKiqV%#b~&hWzx{(9Kt_|GZuAS7zK>zj{=^ zn{G^;AHBC7K8WPob=Oyqt$VWV+VM5snBb917IyyXv6dSiICSC}-%}F~Uw!MlV-`hh z-`K6{*F!5OtRI&C&A1sG|9$XYfG+@Jnb)u*KJ>z=b7x^BMr!?xpIyr$yq(%zk({{ElW?tCrg z`hjz%zumRrhhLX$x;Wqo@BITR9^AB`XZ%giCAIl1{q+%>J??vS z%Nto0Tfgk}L+$hHMs(Zz!SSam*ZjU`SGzaMpE}gO_<;?+@E10${rBuX1NY7BbR^^L ze=4o!;tVafa`pR`n_hnUu=h))^-cFIF7OT9@%Gox=U(-l>y^As@6}GuwYI2>JN($h z>%N@+*6(L(o>uRNJUDaA?4$pf*X7&oGjbfmdxv%yHGSdA_uur6iJH^HU(I&Hg$0kKmu&qgr;aP59`(JKI4u9s*FD#nwnGusq4C+*D*0q|SO8B2bN!o4J z6S&gT!ij?$+o~urt3!8$!Kqp9qDAhQxiqc8^F1~zjX|gv*tqG|p5j9xTpr-m}T%}8aWY?mR6pgrSRvKf_xa77sS7Xpeu_rfB{Ns;=QYdkz z6Mi}PalDAZ)7(yt;~$<-;#z5zvj?b&KX3bs(Cm+)KEY;HpO^POv*~DKOiRYlj0J`D zV*N`U8e=GRZB}}2A=i6J(5}W9JevShhbzIJD8Kf{#uy&!S!rZXsrkdEC73uPw11de zz+0 zsvBddNZG73&p~1Sd)~AFVdl}ImB#XvbLVzFvZ1k__N<3y5-H5>``v~@LstFcj--dJ z0$j=6RWqwgV@yZ**sS9jfqXyv=l+c`REllZMG|wx{Vk6*#&l*3jX0^4Y~EUMdt(ee zN!qM5wxtqK^m^Bq8)FbeU}y|T@!GU>BMOu`Ui3QDW~DI@V3sM}2x`W3W6Wz3(`NeS zn#P#!j8R8HgC|~xD4O+L!I-OYB^SM>_TP;$SHj0;eVVTL9T>0}h1aZyYL!hZKhNHL z#is%zzbOn~oH=KS<`{{mJmQ3FoRxG7*Iwg1C>WMj8s{a+X{m9xNKRXg^Pc3i(KsJV zPA84?mE_O|gDHje=T*DLIWIBv$zg#BwF*`T=1imS9Ve)55@8C;3bcEqq?C%1Qmr)( z)gN*Z8i(dX$hBk6?FG~3%$cv2YSMFi0iUNUK#a+Am*FtnnQp;SZ8@bL-TH(^9D1rW zO3iJ=SuQzImT1m#)Gf*BtZ^QaoF2?6E1FiAH{DZAny=I_8ziQS#(70@Ix=U@Ts;!q zG)%R`T%mDjDIU458s`hi>CT+FMRN;E=~WgxN)2$zi)8AE)QHI*GjQ-=fuO!1!~#yj z0Kwq;%AD)3mmF$;m@{yQc9zBc+6If4?upqr;G?K_MJrz=#iZO%cT@! z47RS-q)7YogKs$&uGzX*N-@S@D^8Q5G@SKRS9~!{4dDhU#TbLFzAP0@SN!^%_{%4{ z)Fvs#7=x{TETxu>&ktQ(piAwNQj9U!LU)eT;GP%Mfrxp}=u(HJ6k`mwXe_O#;k|9Q zgy>Qyq!eQew&Gbz&96H>qwmwDf+?zSj4{}vdav7RwP^blx>S^uVvNBS^(;0k*&_GH znxCF%ucdrnDa9Crtps3oTeqHa4bY`Br4(Zfwx~U`S$VVoYW9r5HeISnN-@S@i`qQh z)=x*Ddsdh7N-4$|Y*Fha;zf|xqk62-rJj*ej4{}vHdwdyQSi~Hb*Xoy6k`mwsO_{_ zsl6qaaJkU@L{C)Vi#c<=SvgHGr4(Zfw$co?9(ix;09}ff4UuDv!Il$T zz0Ch!R&qd>YAF+wF$P=dETxu>y8X*+y400YiZKRT87!sd*RwAiI^9;wuLLQ@7=x{m z23u|JJD;yhxug_h47OY>rRGJyMD>23uoTO3kmr$ts6k`mwax^IrmV+n8 z`yw@4VIjm*=TrR0QRBeX>+;(BayIHxS4b(w7;KGaDYb08SlA;=ml`0Y7-NW6uEAEy zUBg%DQX{1lV+^(?u$0>Nj;lB|LYKN#N-@S@Yoftca{Y!}U8-D4F~(r)MwU{`;nF3c z9d#+6lwyp*)=dUmFZMc^s!Kg3r5IzdHHoFvvT@(5vz~0N<=0=O6k`mwZZ_Cjed}tg zF11HWF~(r)7A;;NEbp8+_jjx+AQJ8?Da9Crt;z7!%f`+_9}m{0PD?4q7;H^pDYb0$ z?f&~fU8-d$Srp5`F{9`=p1&1b-PXk|Aq#b>Xeq@QgRQA7rIwA8e;nDXOAV1yj4{~C zGuZma?4A+2)EFtn7=x{RmQu?`yIaTk*(#D!j4{}nX0Vl;IJ=*2YpIlCjKS7)mQu%T zBc^zk=~C;Y6k`mw3JkV>YdfK*F7=|6VvNC7Axo+G^})%9Pw7%MQi?GKTSW$254_%Y zv@Z3zlwyp*RxwMdX?Sfy<-NMpFH(vz23s=>wx&;=ctDp5krjwB23sX8rPeR%E8A&h z{tC%vjKS7SgDpqJ#38!WU@65IgRNOCrIy26qT`n7Qe&hPV+^)t8*KG^E3Z(ODv?r* zG1!{JQfeB$JTK@TU22t-VvNDoT!XE+Z8pp>s4c+bQi?GKTl2Jdfw0_uadtKx>m}S~ zDa9Crt@!}xb$R2QVas%>52X}i47N&HN-c-mSM*hMseei-#u#kfX0SEklTNdBso$j( zV+^*+SV~R9lsjj?r%SbO2~Rl27;Ke;tH-P2tCKr)sW>Uc7=tZ0OHo}W_wIyy^0E3v z+*s126k`mwJV5BSI@#|Sp-WAYQj9U!TEJ5Nwy=6n+L|M!7-O)t&|oWf@A`JS)JiGE z7=x`v23w{7sNWx@*?K@qF~(qPvBB1%5AK_(OZ`PkF~(r)c7v_I4qD&3vu5jUDa9Cr zttAFqw;Xt(Oqbd(r5IzdwUnh~(Xr5&t%qjoJ1NB&gRNx-Tc@9T?OR>yoRngW!Pat? zqIQFv`|3yUy;8Fk9xk|yG1$5T9(vih`-jml>QeNbcXEs|*jfRumeR%U#-85U{r4(Zfw!E4Y*?RudGoR{G z>JA3R7;IIr6xC&ND<2=4+Euf4o3zCkgRM$n^)#e$lrFVeN-@S@>rR$Z+xdqIT6fo_ z9+y&#G1yvduvLGwpocE?rj%lg!PXji23v~3*7}1#Z`P&Sw1OubV{pE6QCZpCa_Xen1@X1F z#L$i4#5dw38#w(7N@kZ29>mgj<7%_!2lI{JWh5lzd#Stv^^{AEQ|_K$R#d3n7Edd8 zYd7U{<}b7q%%4|0bB3pEntSH_d3o+>)8`afM$BEDx1gx39GsL914fLH>ND|WOasv~`#raQOD?VMRaTBemPR{ci?V$xZhDqwsOz1olla;B9{n_I5lP4LVsQt8zB z9^Fz-(Y(T$^Jb`iIb}2FYCwd-h1WMlWvVX)I?w+G=XgtVY&)x{sMJDlpo-^s%1iR5 z<7L%s|NEKla=x85XXcD~Oo=3wNHyilkZdYl;wdh+l+T%2Sd>>Xt-QoijKf9q7S5bk zh~$=-T=z70QCdk6Y?XT4xh3<<+@o_-Eg}r1GJbRB&zn(H?#`P#&0SDpiSf)M9Whda zC5E3S^xJ}xX*1`=4AL3G-;W^>gUtv(hCmE4Bm5Wwk!VKvF^s{a0%8m)bA*}%RgE9Y z$P+j%4t_WzPvEW(pwGxN2F_Syjlnee2?GOF114XQ)J^%CA{$Uvi?+$v7+_;{G6vY> zCyd6c0XF%H05|0;WCvVQwkcm@fVrw0!zoxM6aF|&vp-TxAAh8YDRgQD!yjp48UrcX zAY&*c&lF4pQVXX6s}%wR*32~qK(>3v5U5NeR5XM}q~sZaqE$2kCC?No15%5W0jnjn z0c+-((%*p9GC*>TffbFkF|d-?7>EYEF_M_3c!};x#cB~#*#fO)jLJ4uWtA<^T8ve; zKsRCwwAS<((T&&wtu@0&bR)JvYfZ8d-H2^WJ}#5o;~7)Xk1y0~ErXwrsm<{75i(i| z`}qi&Kt9HR<;ii1F<2T`7|`-c+4M|M$V}cwIA3u2TVEj)UC%N=)^+$DRwpMU#u6TB@n82!?6vq|3$?+eSRzyX*S?bHidc)~u|~L@ z6#q4agd>yP$he=2j?Bq7<7fsT8n{@AwbFe69L?Si1ZLf3;GO{HVl%kb&=(eueUA8% zYsxM?mh}LpPcyg_;1VPTB)dTIcnMEZ<-lEey}%5?zd*R*;5*^Dk^pc`g)aqu3NRlu zgQIl*1ekv`gCn~?NDN4Jfx<`gKrxBfjf)>SEqsd#r@1M!q@y{F7bHgIr9{T3_`j7P zKH)Y2S1qwLH^DfQzG(2j0_LI_$2Ab1(viOINhnwNk!wm{6#O!PnQF!b(63&Sop;wfWE%KB${z1eUvUYN(?K+rK$Xw4&1zE z^ijFG`!e;d2kz-+^wF%(JHUKw#s!G)31I#(<4p0T{OFo&v0RHEIjtN7(B}eXf*EJh zN9k84F{}`mrqXXYaCe#Y`OU46d@L%?3nqQEloCz;bU;W zUPk8FZ08uq==9uP(KJ7E5jGXUW`P6%`)!B+6|GF}I5;_&JJT|&U7}TXbhfgy z@&I;5XvKk#G=O5kEqyS>a-MR#Y=r-{ToostqS5Zu!wqZ4tLY{SX)&hB+##d*FG|Pm zo?qyn3K{Ns!m3b=Q{|QCbBe9>a};$=q$yzu^*U{?wao3ZZxit9``&#c=N4zi?Np2U zHkt!_12p1n&(vnxn0jm*?=7{OJy6y~BN?{EGBFV**xAIx4sW5g7t|-TQka1o_TRZ} z@w|HmDkR;9A-@-h*JD$3I(;Xz=&Eg8zSux(#i;0Z<(p5oL)+T{T4;g%{`=3pC`C78$u9~ zi4#j6hySqx&-xylupRajThk~sU6Z*DRT~>)BU`E=PP0HIi1GSz43@2DIvQo&2DZOu zBf)0VaITrkLJ9Gg(rScPNZHRx>TzRPwvn^nyn4gT6#8~=8RaW}P%RR0hE%3ab5``h z(Y_jU_2-`l*l6rZtd z>|H7Qeoe9VhH86^5Wbfiw{Vy&+umNOju5XdA?uIGHJncy81RYie%4q&bWLr2QhCjy zqT52VGGiR8=(;>_zRU9<>QP+mh140ywe;pELpi_Db>d#=0HR#IUFM(yVU z%qvrS92j_~E!AS&aNk3vVHIVh=odK{F>h82mcL_$Rpmd@E@Z{9F3^3sKUmMz*;Rx{ z9==SSGoh1PZ<@%sZnE?=&D!O3v>o~@ES#s;dGQwmEl%AzqY1(Em#c{(@hF|nVa@Zr zMp=xT7}4_xueyJ>WM$0j!sIBductRiY`SmlN5QzIeZUA!2WhpR4rAHYN4H!DH|Y}c zIc@9^M{9!pHbE?NT^JhCezMs^s~qDWz56yslAX4s?$f7JzxLn_ss~^w)fYhdjTkLn zekV2TQk1rm9d)x8k+bg38PgsZHiu1$t_lwE-N>nY^)9($;$COI^um4-C)IjY)r0!- zHqPjR8yRVZ^q9O|<DWEY3rgjT8qp~&^&Yc2u<%vG3ZF&bHc(Dt zYKO0&vw`E^?G$J1SA3((@i?mGr|cRj9IZDVE|{cWO*V~5!ygUdzB^X>Vyb`P{F9#H z5S(HKR-Zhts?Vitry^^pqo_*=O|5fj*T0qBmbqUIpEx(t=WRDWv$)Y$q#Dp0*nGw| zPQ%nDvv$vT+v9;*>k`M=6s_%0TE~! zRQ0XtG9tZDxKX50&`8%=9ur?$l}^BnUYcxx8G_w}JDi^fTcGD~@Cv?VsX$a`M4eS^ z&L-?S29HD=y^R&uLtDAhPsnmRFEA9VxQHgDW+r{Uw2#OARO@pB$o7?3oXm)i_;KX- ztnn(a?S$E)Ol_acndqX~*r;w$*%}!KnsE-T8$*-GA!+oxcrm~V7Tph)#YS|!A}uYz-0ZZaJ%JQOqd zqPx+qcVJ^z+-kx4iv94N=75yR3h2@EzT9w_zf>(dGb<9J@JDwwy0n9$*`t6_wM zt+=#7nwCWjv<`sE2+{ItSz_A zUM>xwO{gg-h89obI_LEyeCe0wPwH`di!sW0)@h71;FAfA__3+reLOpB5f5wa%o+Sn zSTxRl(rHKzllQ6Qyj6l|iD2xsp7UtymR4BxzrGu5>iL>kv{Tsf-nO^F`uwYp(lxY~ zb&7DrL)&6p?)`Szq(emY$~IX^wYXt!ME}4*+WfQbXrF6C^^MAt>uTK<7Hb)mnikiK zu*PNbdF6-jSV!KTrc~gC%5A|hJPaodR~j-cCU0`tN32L$Ro`tlDhR7I4>-r*(37fW zInDbX*Da<3CJnuaPFi*olab?HxnOmE6^xm+Q2UW?fi*_`;Qq^^u1>DY!^sGpi5%)g z)B4;clXXTH>$IoncG0Jw;$Xd6#OJ+!=afYtCPed0OpToXbg2i4XC7+~ZZYMxM?DdV zv;Eb0USlgIu+hm2LA^bFYkkvVmg5CKXhs6;{i;bjw#pcF9CF=0l9x!kg*7qm`sk_ zD%~v$VhY}`5}m%fx}fOP9>F|i*VdY$k^RP&5(COYYhup6E3ji(tC#XTe1mhQIQpg= z;b0*bYi{?hIfYM^o)6_ywvQGgq(SI}Ivm*=hB7Vhns6@#?Aa*D=GK2AK%@tervA99 zl9-~BFu=P%wyc_MYHGH}6~FOWndUivHoPoW zfB8s-&qKV}Sjl(}ChDS1?}z%2tdfo|+L-9}UoI_HHiqlS&!_~cd2|0OxlJwWF*t8Kt|q?3Rb0#xsnhhC^}hJ2rrTDVIiFO_ED%X%*+e0HafOr=rN|{`G(g-Ff6pfP`~j(Mv#8FdC6?hMJoJk8C<)&;8xb9tIxSnqB04IJ zlhiiw@QSzroB-)q!f zusF8)@oIMJnh9)%kbyJ6WyPCijAF6eYkiG`lIMjQt$JOY-Jbn~MgmN6b>a)G zz3gFK5Fu@Fm78Qn$2|Yk)izgb zY>N14L9sJx6{(H8!dn(;RV2CdyevDp#Vu?UoXHXJTraJMjGxX8W}tQW&}!NN2sLyCE?R5!%5V>GrQFpc=)W+&j2@y>@vLi9%awTvThY<>OTzG% zN`60U{jY5w4PQJm@^=#a+}CAd!Fwuu?UlslZTV>3@6?_GO4pg>W!s|Wz8sFP#(M)ge1)nF z$>xA+YH1^@!aBaTC3ruzP(qlE={ft#j;GgXVyH%1CZ5dr2a#djpQ@nB5K#j5t#69Y zCepud>r3ITdx_6+^0f?kILHWOH+`_h zPgaT;*8X%O6x}3GKWp~$-ZwK$meQ|+hEw*#C9?AmNr)`%8YX|O`v&_EYO?>3+HiG$ zK_~nz!OG0Zz54woJN09i_iYk6F_l#8ZZ<`k7h0B?8)!1p_HO>7qw&{Fm%Tv1khN7; zaHS}oXTX@V$hXe&sxc{DwXUwGNHwCTbe{RawbT1bF@tYO&t7$}i8dMie8vy=OkhX9a z63U&O)}62HoWOruq`oYA!RGoqIi4D(q`ga}6X~zCad0_sU#q|U>PGL67ec=rpoCEISi`vywX+if0jt&coK?-@Rjm5v;|3-z?%g@lMCvN95tyt39mHK;(NfMU=-!-@jT4Y=J>XUmmv7P&&@cYgs zu(6GsV=i}~_t@4yW_~jDS*)0ODnxADmLfOJEQ4l6imtV=(ZA~O+%YD;(>zG@5(SC$oF2;5N5x2zN* zC6gOZl}xYkZcx^5k4hD&tAUTYE$5WIwvo6+#h=AIGwalIrwm#Uv_+2395CXIm}SqM`|bhK}Loeod1% zKT&Gcpl8EW%wIC(1rxdH&%R$P#PCSdv7H#p4!4XDTPecM#D{82TjMxqAZi$87mQQW zu=~~(+%K~~j!*FN+?C#mI=7bTxEHCGK*b1garVC#5Oami_WMFs5UIho z)t#GzA<>@#E!IS!;e;Wo#wsoCpYwd;v3t{Krn%25;%U&BES0?Cg7!O?EL^Fd#nLrT zSgq=6p_#-}+7zjvI;Wk-y<2h0kYspd?$?aXp^PRE=ekf%LtU&{<74-r~6vD5>t5tk@6_t`ckbP_J&l+ zf*8rI`0^HCciaSrbKO*dyB12;DRzbkpHXg8Dy+hYz1%sY7?SuW&d=N3N$)8>`rb<8 z9o@k7^p1;(6Jh3T{Mz{v*F1f;Zz}WmsJO3gZ}kRbQIv!R{?NESNOomfb+2C?N?f(- zHKQxV4iibt{5Z+BgI~eax1t>t1i7XF`7*qthWQFTVqB(hjGM(ud#HU9o9}HuuEr&H>-J7w#JG zaT5i|8~*wXSE9lCPPJ;vl5j5YY0KvFwGt?9#O#v&4HK+~vs?>{D>T@rwG=;F-fzbX z<&K};Zj%%s_af`}coua%k*uL>pL&_=d{)hbmn;93q*|NNO;Zv!k{+pgSAtsRCuNVC zzZFz65@UXCbsVy!i?SDZ-_4#X%Ne(xp(g39Q1Fd0ZEzb~j8|DZTm8|PbP;_-=D6>g zz7TI(p8g_(PK};h;i#t8O@WWF@>@dTDrFBQYg+F>EtnfsL*yt1jkDechIgiC*|MM6 z4p8`T&nnxUE$H2tnj^h6Bt@zu$mJzkUqS%^`7X!g&IgRO22t(D3C=47LI*(TxFjwK&K94KpddlANg#o=uNX zN0BjnK`|wE_t5!QKYQ-%)KK(!TeE0XT>7{wlwEG^@b&il`E)$}mbs=M%En2?R2MWF z6GMNJ$+hw2btu`gCgZ&fr;r+@;m0H_tM-$pTdwyFv?eP!^+w(O8EY4vpnLRu(*Dq6 zg2_aKSGQ;|cwoAnF=6Q;xD4^HkPpV1>h6)(}SKs+i`Y;7nJlwCn1pur4=? zK{icLLt@bR2CA835dXibv2 zV8oZWdhw^QTgJe**c?Jl_Y-sKP^ zpUkWgm)!js^2w`Y}P zlc~mgM}AimX|Tg7muRowHr1-m|FrM2mTSiD!q+g%y9OWlQS%PLZMO3l&^Y+lvx2MD4I7s~2#Q);u0rK@!elyhrD4fU zR1YZ(2j5Rl&rsZw;LwHv6F``IP12h$4FjwS*fH({H;DEf$?b!~|c>hq~|F>G|p1M^RIu!D216`tg#3b$Ryu``cez^zqV_e>BZe0TV!Cqs9d} zvY(+Hd3E!*a1AXh?oGKt=edez2E=bq4pEMsmN$_~+ z)+>WV7!L+bSWKs`)2t@`hWJy(m&47iwD)iyK$acrg5@jx`?{yFZn&{Z#%z*D65r_U zg|~)iHaUos%6pcQRlCh&*?3zrpve zrvzjEHUAfW%b4hLIT~?9EZrg_R%>rEF1nt!Gh&G3oqf)`mr)+pJ}=Ay$+FMY;aDJz zv~9h=#H4hQ$&|X(YbxPvw`%2z{DN%9D=Cf7M0r<+I|hSF)$K+%&|>;CX`!M^o&)1bJ6qI&rB2JhJI(0c_@|66;=gm-ML;Iwi)l; znE_>#zmUF+jm8%x9u%bw>4%}+SIcf|4)8H_z!=K9tSPpd*)=1$xaumM>edzZiC%8d zB5jF^-prn3ZMtP9KToZOmv_V2h148dB&xQ-yIwnPTk_|P^3QEKRED-@20U9LqlGG) zagXamd(W7PMT-8SAZfnUqlq^1(LczGrLKSOwxpV9Io6$?CdEx>Jp7EW8V@eWB(<(4 z@)@}a|GY^5@?}OEn(b^rG+_?L)zM|mx4u?gIPxr{2>1Ocwt~v~lKE?rM0B2J0S27Y z43C}iYC6C3QeYIeT0Nap>eNi9zKMGw;ajtDxlzR>;buo`dp*{#3%gU<9Cv%&GbhOf zcO}JZygr5e)V;k?GCFvDBSg{EkznyH&%`y%M6KixL#Hufbi<$P(`0jARA-4@AiIm3 zAN}j~-L7lQa+oy{eo{*$BlR}UmbYMDu)Me2w)UdTIQ?Ek&z0eOQw!1 zH+a{iMz!n1Yw84Ymfc1rY+jdT@l)M$nw?>OTB6qK%JncS-h^MyU6F_V2~8ldWZcSr z)c#e$v`~&7G57PGk>Q1x5!_Ft9H^2m`YN$DShs9F3rr9dEf04zygAwASEEJwNd=aT zp2zUgT;Gi-xNztR{NJ9p1-mwV$ z6deu~Su<7*A^hClqJkaolQ&J1){CcjmV3#BMgz+As$`)A*iM?Qzp|QOu1nL>Rkf*v zH+hb#LS&aaPn*Q>RK>5kkzt}j+iR_sk7XDIF1~tSx!+FrRhFf`R$Phg(dOG`66OwO zspQKO`~nhOHeu56P`IQd;MrF)O{-YFxUhO685~&UBTO?u&zAfeP z4hgvKfmGe+td%Tw5r%dtrre`G5rtS(MsvA)PvS{p+}oc!KT^C$>P^%7{V7*Nw3CU; zo%q>ILf4Y>Yv0)P^Qi94t88sw<)+9A==~8GT0%B>U1Lvm`U){ry?@4QwF<^ArTZ~6 zQ3QX7ZE~fLsR9B_0AC;q*D%#~hQ}k&UvZBW$_!~+vG8F}whu7&zvXu}QR-cStoJ1$AnUPlOc5|JZXBs<0hgf48Aua1#Mjgpq?8n_gS_l#Mp7Ae3`2ZRv z_~%us?^x#&SWGuto(4iot}QRkM&M$Z+^}EZntg~(v$FVEQR_5b`+dvlcB>;dk{KwW&>FBQf2qm+B#5t|f47epL2^v9jP>>sL%- zI?Ex)_X74&vZ?Id8S8PJ3eJ*hX^h_r#IUyqv$d6ZrN96^Y=cVxq=`bwn z7rN=y+|<$>Er)#+Pze{hRWtdZ%mR9+HAJ0N?Kq!RkjUV84p8Xjj>UG!l$6piv4K;HikPW#?+F2q_((+GOCV2L*^ z@*uoCX$*EoP6Q#3^Nc!hLOf~Q`z)pN>+gw|r&103&W3X zPX0!Zy81o~p5nDIk$AP19W8%*lau+!OAG>$1HD&tL`l*Hw*S>o3W+^a0! zw;d`AGQx!xF-ObAdiVv-#huDiRi5R-St=+=6;$Q>kw7%0qWJ9=_Sf`@XZ+Io+fH}; z^Is(1{Bo+JSG zGeO_`Je$RWY4*)f@M~$wu>BOt!+F^TJ4+(p^hhYjFL}e3q(-dlRKczQGMk)|*{8 zkD1{b(ti6fc63jDga9TjzOnN8z)NvIF>edL4j5XJf%*uifYrk{kK&Qzqd857GePs^c`TA}rCENHntcUXNUx{?X5|7I3~Qf(hx!`{A9Y*SiZ z)M9m-)%5-XRkQyyW*y zqUx`nc@lGAtWwLFwCl{a1x5L0R}C61P)cA#(4uEC*|mHS)riQSWPCeVO1HKQ=A12km94 zQG`F>^C^BGH@J(nms=}JwPD_SH(D=dK!DJoK#!HeW=-@meypeUv+KO6jkoaT7^t#b zL_H&UR(i&_9~8~iY_Y^9M=NFz3C&CqYXyv|mjVv}$5W;J?%=@W$?Q4t5PXX`Usbx4 z;oC`p^vM|w??xahsa1lc1SGCw)=r8Eq)WmTP6({Mv5WG2Ws;7!Z=nrL3!5*$c+{C{ z|2;F2`8FOQ6NxpeQALA!*2D|FHefePFq%BZ~LP5G$&^0)69+uY?X}M}&y+R?8%#icUG)hWhM0L^@7 zyId|UDPwVAWbr~+RhNa`w(ACVvSR*AK8Sn0 zilB(ZW-ix-M+mnF!KSK3-M!t@eOk~?Dy>AUPRkf=)4ZX1eUv3r!4qD&<-VpUg{(fEL?a;>(;HhMRES=5s|o511gs|gtzyi2LdYkg5~jO5GsTtKYx(m@xhSbF~^qRvB%}X zmkDShLF`B%S|t&Kl87-lVjKv4-AqsnoL3?l;fSyhumAwvD2aH1!Vwg|lSI5h!a%j* zh{q^2(3HA)LJ1&tHrNm9=CQ&05fpdHpd^bS?)!qH;GiP1bqnNhp8Jttw-o2O9|FGm zexN&^7C^_xWq}}|pDx+DFXZBg`+i^{0B6(zXB5aO!Se%-XgKBpK@`v8-+1CtJX6Ok zNC@PRsr!=ykaoZ^4}{V@Xe1Isajg6y1K=nFWgq|*@N|KSKwh0dCm^J#3=mja6ggyg z@Ck~$fr}4DnZ^dLJ@R=03ia=t@hD-yc{&vkLiGPW&q+!iB|z+Z1q9GPPiFl4XFN){ zaGnkYAY>@vzt41%l1GV_3sp!#5=k>mci zf(}u#0rNnhTtP72ED$D{5eTa)0mjlLl?iu6`wKa8=9v24jhup6_^AY5K z1SK3nnMY9Z5!84DjUPdaN6_{WbPAaAQPOCSAoe3j=m?TKf((uzyCcZ+2ns!dnvNjQ z=O{|X#t{SqW>OUH;t|Au1gRfE7DrI*5hQ`AJD7ao$ceL6k_RIcnDkq~)4#x72lyyB zqP78CS3$uT5U>>FGK1)@o5luaN??j7@kP}Ce$plb%=`cX$O!>LBmZ_%-vIK0pPB)7 z1FD<`pmhgjO8{%~p=E+vvys+G8$4VTShMSaHM!`x>2GpGflNRS7$wRX@cjrxiu#=k{L%--MR){(GDU#{iY!|i==q1~Z{Z{jFRDAn!Q7-Jw4IRkU84cA_{?5XhmA#37?) zfs+xC4mrSF6dkA$6hsI>C=QUy1vm~9Dj#eV3Ie%Jf#X;=hvlB6K~aMeQ00PUdH}~^ z`dhiyK;}V&&wrsC@S{moOHmM58%HGWFgn)LPnXdxL)Q8@v~Mi}I|tn7qOWIE=lC>S z+OnhAl&y_+z%?eqn{Hwb5HlTm+VN_ErbKQ4moy}`4gJ@bAcWfx#~ifs<_i^WOM$C0 zt*2`Ua)jD$Wiaf(v!9xA740ffh}Ce+$BXgwXtk}WOGp<7C+e3uLH3<%+tsXR=an__ zQcho{xwmdj{!O`Kn<=E9K%rRJ&9Hs1pr&ZX)E9pF4A)m`3sdV$w3ucx=2dTOoIq^?^KuO5-|5}tE@LOjvEkODxP!RZg zIEcVOiW;c+2k2uA(#I3f0gf@3K^kD9I>v~C7(fCF^ZR$vpaduyaybDY{*vuN)c3W& z(}1}szubT+07+~Wo&1vqT%Mq4;P?e;{6u9;{-il|f+qLolfFM`z@7{RJfNa-RBQ!5 z|4D;ff6>4t3|Sxlq`*IEz+5PrDDVp=9q}q)@PpL9w+m^(pn)?LIEqNZnvDOX0Y@$r z4P3xL?m=15Z~Q;Y0c(qr1?H%0+0*_>175dd9rmhF!2hHnK++%=O8_dtTZ;LUh7d^u z&LE&HXbH^o2_^)Lse!~8pyrz6m@IMt7nqJCx#*w}K(q>w3rtoA80;gA=KGAkV=lHXw%mw{L5~ zFIG{W;y{u_TD_iQ&+3gJ3P?zr6TZ>F`Tf|xoT=l_rDHCjBO?=%=7g*>NG@9N7dYx} z>QEeWeF89GLeiX&1+M+avMO>?PaSh@AbEiP3eudAbr#75S}35b@uquY$6VlD2AGgE zCuETV*kf6_&0(*PxkwMVkTfS`ftydqKGHQMzE>Y}F&%IrX->#O*6qlDzJlz{564{K zoer2#_5b~PffM4ftdNAPo5x(T2V6*+6SB@Bxsc-*fGXTp?T)#?yCpCoX->3@62Kn! z4bacwvFA*i11==Z30dGAe5^x;R5;Z!m)`*wlIDagY9tpp$ZJt6DKQZ&XfSJMF( zlIDc03rH^HOa(yYW39o*T!RN(NSYI}E}oE8>3P@hm}~xk3rTZA7TpmS03iKR9!FQ% zKHx&qoRCF-#08EN@Om9{5uqkQWb|P$7g#tCFdz)X+WYORdIkUkMPojY1LmXB6@UYr z?@-PLLCDz3;`g&VMpmYOoFCHwv*&Rx4>#b;#m?Bu-ps(k@nBj%K%6`?urRZSSeOB> zUyei@-*q-KaB?$3@*$^RuqG$j0Pl+c!*5c6VgTHsH$GIJ$DwndqtinVL`Mjumjikp z`XdC2;_5L1Me!Q~MZx<|ir)|@3ci0*{DwGil7o_ZsFwr(JO4l)kRGm02Si7wC|R8J zM+j7Xe?y=sxc*7;8{%)Z0hNg=>O_42w83xgc{r|eaRZ(hj?$5Lo@+-aByi}Rhnt6s z2bBYQ=Yc_f0^WJr0aK0fpb!4dJI`TcuET!%H}5=;fy~{1^k}4ap5LNHg8ZAn0Y)Oa zj~XOMTlH_=TYdp_ZvdLtfSm;<@ZaC)z}2GXfCi)k6O!(?l^eu?>%+o7=>C;g4A8K} z0}e2O)%=^67qC3m0~(MHO#iApaez+wpXJ>->4gTgKCszA?N1#-v$&wOYB0zAPzL^FZ(J1~>=M_?;}7)Laq5X`JYM3X}JQ+i*Z1X+X*tt`TZ zSr*~MDU0|7H-PIKG>8KkbijcDQ3HNKOArI{8u&%+OSJ+`sD~iX4v(-2yJOKA;W{TGxOEc*CYNC52F`pM_9fA%Re?ldKX?5h8CqzzOLv zp-gJ~J3Ia<&8DmKQHju-OmXLM~h{34RJ!^hTNxgu9 zJ7l@ouuVdf`%Ha3Up3zs*}~D5YTSO+@RfcGGG^4Aes_2ts-J%qrsiF5_r%|AuwA$N zQ11Wc#>C@8p-2CJzdZ&gOeh+tRZt5`blNI^-j0GfP&80)Amm6u6aOa-ILATJK<$I+ z!<&11D4IhzzbO3S%_msSF$P%Ak@FIWfkF;xz#C;Sfj6Hh+w5@91a<2R<}rak$OO`W z;Uswu&cSw}ZV|Z-Frdtnw}`0i3~*@x)90j^cIc7&>?41V8a{ao2xTpc=Rb@F9d2zV7v?$m0D?Hb)aESsw4zFH4 zu!>N&(UBGPFMJ$w^YC*XTT!QxJ`P&|{hU8&>EEoV7yq!1{$@o*0{p%Ip!=H@1zuPa zpby)i`Z01>=Wo^#Naq63c>gDK;9v^|Xu|#zx)Fdb_J9Tek?C)82LKvJaK!wU{$`bd z^^-d6R|mBJ%8F6~=(G=L!J?6L|FDjLxd!6?kMjN-*3o^idjDnX=pcCT|A2Ay`)fj| z#ZS@X_{AY`rNIEUfPn;d9n>lEJt9R!7h*&LF{~I^dly!Uw0ID@^wf|7RN^_6!V zcprg{H`(vgz%xd8-6EkZqFw^bVyy>GWV+`ipsg}c@Es2VtJ<}F;8hORuF~7Sr+g&| z-qypvPt|=Pu&PJlhv4CUs{n;qI4&jl{scChwGCblV&KpgI8wAQNGVAmRv#XPgrIeP zbp(+8eZQUQeKZJxSexHAh!6JzkpyCO@bC~2s+%H&`~3iO-~?hVu(}4|l^6v?54>)H zkf5X$c#{Xsg^Qq=7~1W(0}@Gu`-5B(fE@8~3~Z!OR6ziD-A6(=tOa=H2)-ADRSIgW z0VsjcNgB|QGX?4aKJaK2T`^n@4cY=UAAH2`vW%*k1gdIC4FKiW!M}e5G+P7OzHRHIFpKu^1HI%rxaL6WV;s?pd+$%i@35@4Juy% zn-yAHt^?4Tn*+kZ?gloq7#+|VL9rMbPyrN#egr{}AdDjj^9aH^f=(Sl*hdh~5p?

I;F<;|w}+>;Q8d3thd(wm!J2{T_(=rv=^KDK zHarjQ1S|+Ga3#USf&2x%5`%{4@B7%G9**PNf^mqBcZuN#Tu7S#z|iZn9)EJorG3D4 uVCem}hN28Ta1}k7?f|C;tp%P99YTlOX8$-h_$R?{+k$_P9@uez;QtRmnSnt7 literal 0 HcmV?d00001 diff --git a/libzip b/libzip new file mode 160000 index 0000000..0581df5 --- /dev/null +++ b/libzip @@ -0,0 +1 @@ +Subproject commit 0581df510597b46c28509e9d4b5998cf5fecb636 diff --git a/utils b/utils index d4d0be7..f4b05a3 160000 --- a/utils +++ b/utils @@ -1 +1 @@ -Subproject commit d4d0be7e7a278fc2e58f04f9ff77ac26170bbcc4 +Subproject commit f4b05a3dfc07e93f9bebc0de1de7e86fb3fd3a83 diff --git a/vfs.cpp b/vfs.cpp new file mode 100644 index 0000000..002c586 --- /dev/null +++ b/vfs.cpp @@ -0,0 +1,161 @@ +#include "vfs.hpp" +#include "wchar_util.h" +#include "str_util.h" +#include "fileop.h" +#include "shlwapi.h" + +VFS::VFS() { + WCHAR exePath[MAX_PATH]; + GetModuleFileNameW(NULL, exePath, MAX_PATH); + std::wstring path = exePath; + std::string pathStr; + if (!wchar_util::wstr_to_str(pathStr, path, CP_UTF8)) { + char buf[MAX_PATH]; + GetModuleFileNameA(NULL, buf, MAX_PATH); + pathStr = buf; + } + base_path = fileop::dirname(pathStr); + base_path = str_util::str_replace(base_path, "/", "\\"); +} + +VFS::~VFS() { + for (auto file : handles) { + zip_fclose((zip_file_t*)file.first); + } + for (auto archive : archives) { + zip_close(archive); + } +} + +bool VFS::AddArchive(std::string path) { + zip_t* archive = zip_open(path.c_str(), ZIP_RDONLY, nullptr); + if (!archive) return false; + archives.push_back(archive); + auto len = zip_get_num_entries(archive, 0); + for (zip_int64_t i = 0; i < len; i++) { + struct zip_stat st; + zip_stat_init(&st); + zip_stat_index(archive, i, 0, &st); + // Skip directories/folders (directory entries usually end with a '/') + if (st.name[strlen(st.name) - 1] == '/') { + continue; + } + std::string name = st.name; + name = str_util::str_replace(name, "/", "\\"); + files[name] = st.size; + } + return true; +} + +bool VFS::ContainsFile(std::string path) { + path = str_util::str_replace(path, "/", "\\"); + if (fileop::isabs(path)) { + path = fileop::relpath(path, base_path); + } + return files.find(path) != files.end(); +} + +bool VFS::ContainsFile(std::wstring path) { + std::string str; + if (!wchar_util::wstr_to_str(str, path, CP_UTF8)) { + return false; + } + return ContainsFile(str); +} + +bool VFS::ContainsHandle(HANDLE hFile) { + return handles.find(hFile) != handles.end(); +} + +HANDLE VFS::CreateFileW(std::wstring path) { + std::string str; + if (!wchar_util::wstr_to_str(str, path, CP_UTF8)) { + SetLastError(ERROR_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; + } + str = fileop::relpath(str, base_path); + str = str_util::str_replace(str, "\\", "/"); + zip_t* archive = nullptr; + zip_uint64_t index = 0; + for (auto a : archives) { + if (zip_name_locate(a, str.c_str(), 0) != -1) { + archive = a; + break; + } + } + if (!archive) { + SetLastError(ERROR_FILE_NOT_FOUND); + return INVALID_HANDLE_VALUE; + } + index = zip_name_locate(archive, str.c_str(), 0); + zip_file_t* file = zip_fopen_index(archive, index, 0); + handles[(HANDLE)file] = str; + return (HANDLE)file; +} + +bool VFS::ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead) { + if (!ContainsHandle(hFile)) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + zip_file_t* file = (zip_file_t*)hFile; + if (!file) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + zip_int64_t n = zip_fread(file, lpBuffer, nNumberOfBytesToRead); + if (n == -1) { + SetLastError(ERROR_INVALID_HANDLE); + return false; + } + if (lpNumberOfBytesRead) { + *lpNumberOfBytesRead = n; + } + return true; +} + +void VFS::CloseHandle(HANDLE hFile) { + if (!ContainsHandle(hFile)) { + SetLastError(ERROR_INVALID_HANDLE); + return; + } + zip_fclose((zip_file_t*)hFile); + handles.erase(hFile); +} + +DWORD VFS::GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) { + auto f = handles.find(hFile); + if (f == handles.end()) { + SetLastError(ERROR_INVALID_HANDLE); + return INVALID_FILE_SIZE; + } + auto data = *f; + auto name = data.second; + auto size = files[name]; + if (lpFileSizeHigh) { + *lpFileSizeHigh = size >> 32; + } + return size; +} + +DWORD VFS::SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) { + if (!ContainsHandle(hFile)) { + SetLastError(ERROR_INVALID_HANDLE); + return INVALID_SET_FILE_POINTER; + } + zip_file_t* file = (zip_file_t*)hFile; + if (!file) { + SetLastError(ERROR_INVALID_HANDLE); + return INVALID_SET_FILE_POINTER; + } + zip_int64_t n = zip_fseek(file, lDistanceToMove, dwMoveMethod); + if (n == -1) { + SetLastError(ERROR_INVALID_HANDLE); + return INVALID_SET_FILE_POINTER; + } + return n; +} + +std::string VFS::GetBasePath() { + return base_path; +} diff --git a/vfs.hpp b/vfs.hpp new file mode 100644 index 0000000..c70821f --- /dev/null +++ b/vfs.hpp @@ -0,0 +1,26 @@ +#include "zip.h" +#include +#include +#include +#include + +class VFS { + public: + VFS(); + ~VFS(); + bool AddArchive(std::string path); + bool ContainsFile(std::string path); + bool ContainsFile(std::wstring path); + bool ContainsHandle(HANDLE hFile); + HANDLE CreateFileW(std::wstring path); + bool ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead); + void CloseHandle(HANDLE hFile); + DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh); + DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod); + std::unordered_map files; + std::string GetBasePath(); + private: + std::string base_path; + std::list archives; + std::unordered_map handles; +};