diff --git a/harbour/contrib/hbzlib/License.txt b/harbour/contrib/hbzlib/License.txt
new file mode 100644
index 0000000000..0fd5e9833c
--- /dev/null
+++ b/harbour/contrib/hbzlib/License.txt
@@ -0,0 +1,73 @@
+/** \page pageLic Licensing information
+
+ZipArchive library - creation, modification and decompression of "zip" format archives
+Copyright © 2000 - 2002 Tadeusz Dracz.
+E-Mail: \htmlonly tdracz@artpol-software.com
+Web: http://www.artpol-software.com \endhtmlonly
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+*************************************************************************
+An English version of the \ref pageGPL "GNU GPL" is in the gpl.txt file distributed with
+this project. Translations to other languages are available at:
+\htmlonly
+http://www.gnu.org/copyleft/gpl.html
+\endhtmlonly
+
+
+Distributing ZipArchive under GNU GPL implies ZipArchive can only be used
+with software that is licensed under conditions compliant with the GPL.
+Embedding in proprietary software requires an alternative license.
+
+
+\subsection s1 Alternative license for use with proprietary software
+
+
+If you want to distribute software in a commercial context that incorporates
+ZipArchive and you do not want to meet the conditions of GNU GPL
+(e.g. an obligation to provide a customer with the source code of your
+software that uses the ZipArchive library), you need to have a commercial license.
+- The commercial license provides you with the same rights as the GNU GPL, but in
+addition allows you to embed ZipArchive library in proprietary software without
+affecting the copyright of this software (it removes the GNU GPL obligation
+to publish the source code)
+- The license gives you royalty free distribution rights
+- The license does not allow you to transfer these rights
+- The license is granted per developer
+- You won't need to purchase an additional license for the future versions of the library
+
+
+The commercial license is available free of charge for using ZipArchive library in:
+- freeware software (freeware is software that is available free of charge, but which is copyrighted by the developer, who retains the right to control its redistribution and to sell it in the future)
+ - excluded is software which is associated with an equipment that the same company manufactures and which has no practical usage value without it (e.g. software used for maintenace of machines) - unless the equipment is free as well (?)
+ - if you decide to sell the software in the future - you will need to purchase the commercial license for using the ZipArchive library, unless it is distributed in the shareware way - see below
+- software distributed in the Shareware way (Shareware distribution gives users a chance to try software before buying it. If you try a Shareware program and continue using it, you are expected to register. Individual programs differ on details -- some request registration while others require it, some specify a maximum trial period.
+Copyright laws apply to both Shareware and commercial software and the copyright holder retains all rights, with the exception that copying and distributing the program for evaluation purposes is encouraged, subject to certain conditions. For example, some authors require written permission before a commercial disk vendor may copy their Shareware. )
+ - excluded is software which price for a single copy is higher than the price of the ZipArchive library for a single developer
+
+Extended Licence for HBZLIB (library for zip compression in \htmlonly Harbour\endhtmlonly)
+You can create proprietary software using hbzlib respecting the follow:
+- ZipArchive library must be linked together with hbzlib
+- you cannot use ZipArchive as a dynamic library (DLL), it must be linked staticaly with the software
+- the commercial license for ZipArchive is free of charge, but these grants are valid only if the whole application is written with Harbour
+
+There is a fee for the commercial license for using the library in the software not falling into the mentioned categories.
+
+It is recommended that you should print two copies of the commercial license
+document after you receive it, sign them and send by post. One copy, signed by the author will be sent back to you.
+Please \htmlonly contact the author or visit the Artpol Software web site\endhtmlonly to find out more.
+
+*/
diff --git a/harbour/contrib/hbzlib/Linux/Makefile b/harbour/contrib/hbzlib/Linux/Makefile
new file mode 100644
index 0000000000..af73e9f967
--- /dev/null
+++ b/harbour/contrib/hbzlib/Linux/Makefile
@@ -0,0 +1,91 @@
+# Makefile for ZipArchive library
+# Copyright (C) 2000-2002 Tadeusz Dracz
+# For conditions of distribution and use, see copyright notice in License.txt
+# To install to /usr/lib and /usr/include, type:
+# make install
+# to install to a different directory change prefix
+
+
+
+CC=g++
+CCC=cc
+
+#FLAGSD = -g
+FLAGSD =
+
+ZIPARCHLIB = libziparch.a
+
+ZIPPIELOCATION = stl/zippie/
+
+prefix = /usr
+libdir = ${prefix}/lib
+includedir = ${prefix}/include
+zipardir = $(includedir)/ziparchive
+
+AR=ar rc
+RANLIB=ranlib
+
+.SUFFIXES: .c .cpp
+.c.o:
+ $(CCC) -c -I. -I$(HB_INC_INSTALL) -o $*.o $<
+.cpp.o:
+ $(CC) $(FLAGSD) -I$(HB_INC_INSTALL) -c -I. $<
+
+OBJS = ZipArchive.o ZipAutoBuffer.o ZipCentralDir.o \
+ZipCompatibility.o ZipException.o ZipFile.o ZipFileHeader.o \
+ZipMemFile.o ZipPathComponent.o ZipPlatform.o ZipPlatformComm.o \
+ZipStorage.o ZipString.o zipnew.o zipcomp.o zip.o
+
+#OBJSZLIB = zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/uncompr.o zlib/deflate.o zlib/trees.o \
+zlib/zutil.o zlib/inflate.o zlib/infblock.o zlib/inftrees.o zlib/infcodes.o zlib/infutil.o zlib/inffast.o
+
+OBJSZLIB =
+
+$(ZIPARCHLIB): $(OBJS) $(OBJSZLIB)
+ $(AR) $@ $(OBJS) $(OBJSZLIB)
+ -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+ZipArchive.o: ZipArchive.h
+ZipAutoBuffer.o: ZipAutoBuffer.h
+ZipCentralDir.o: ZipCentralDir.h
+ZipCompatibility.o: ZipCompatibility.h
+ZipException.o: ZipException.h
+ZipFile.o: ZipFile.h
+ZipFileHeader.o: ZipFileHeader.h
+ZipMemFile.o: ZipMemFile.h
+ZipPathComponent.o: ZipPathComponent.h
+ZipPlatform.o: ZipPlatform.h
+ZipStorage.o: ZipStorage.h
+ZipString.o: ZipString.h
+zipnew.o: hbzip2.h
+zipcomp.o: hbzip2.h
+zip.o: hbzip2.h
+
+clean:
+ -rm -f *.o *~ $(ZIPARCHLIB)
+
+zippie:
+
+ $(CC) -I$(zipardir) -I$(HB_INC_INSTALL) $(FLAGSD) -o zippie $(ZIPPIELOCATION)zippie.cpp $(ZIPPIELOCATION)CmdLine.cpp -lz -lstdc++ -lziparch
+# $(CC) -I$(zipardir) $(FLAGSD) -o zippie ZIPPIELOCATION)zippie.cpp $(ZIPPIELOCATION)CmdLine.cpp -lstdc++ -lziparch
+cleanzippie:
+ -rm -f zippie
+
+install:
+ -@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi
+ -@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi
+ -@if [ ! -d $(zipardir) ]; then mkdir $(zipardir); fi
+ cp libziparch.a $(libdir)
+ cp libziparch.a /usr/lib/xharbour
+ chmod 755 $(libdir)/$(ZIPARCHLIB)
+ chmod 755 /usr/lib/xharbour/libziparch.a
+ cp *.h $(zipardir)
+ chmod 644 $(zipardir)/*h
+
+uninstall:
+ rm -f $(zipardir)/*h
+ rm -f $(libdir)/$(ZIPARCHLIB)
+ rmdir $(zipardir)
+
+
+
diff --git a/harbour/contrib/hbzlib/Linux/ZipFileMapping.h b/harbour/contrib/hbzlib/Linux/ZipFileMapping.h
new file mode 100644
index 0000000000..a38e6e9d11
--- /dev/null
+++ b/harbour/contrib/hbzlib/Linux/ZipFileMapping.h
@@ -0,0 +1,70 @@
+////////////////////////////////////////////////////////////////////////////////
+// $Workfile: ZipFileMapping.h $
+// $Archive: /ZipArchive_Linux/ZipFileMapping.h $
+// $Date$ $Author$
+////////////////////////////////////////////////////////////////////////////////
+// This source file is part of the ZipArchive library source distribution and
+// is Copyright 2000-2002 by Tadeusz Dracz (http://www.artpol-software.com/)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// For the licensing details see the file License.txt
+////////////////////////////////////////////////////////////////////////////////
+
+
+#if !defined(AFX_AUTOHANDLE_H__D68326EA_D7FA_4792_AB1F_68D09533E399__INCLUDED_)
+#define AFX_AUTOHANDLE_H__D68326EA_D7FA_4792_AB1F_68D09533E399__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include
+
+namespace ziparchv
+{
+
+
+ struct CZipFileMapping
+ {
+ CZipFileMapping()
+ {
+ m_iSize = 0;
+ m_pFileMap = NULL;
+ }
+ bool CreateMapping(CZipFile* pFile)
+ {
+ if (!pFile)
+ return false;
+ m_iSize = pFile->GetLength();
+ m_pFileMap = mmap(0, m_iSize, PROT_READ|PROT_WRITE, MAP_SHARED, pFile->m_hFile, 0);
+ return (m_pFileMap != NULL);
+ }
+ void RemoveMapping()
+ {
+
+ if (m_pFileMap)
+ {
+ munmap(m_pFileMap, m_iSize);
+ m_pFileMap = NULL;
+ }
+ }
+ ~CZipFileMapping()
+ {
+ RemoveMapping();
+ }
+ char* GetMappedMemory()
+ {
+ return reinterpret_cast (m_pFileMap);
+ }
+ protected:
+ void* m_pFileMap;
+ size_t m_iSize;
+
+ };
+}
+
+#endif // !defined(AFX_AUTOHANDLE_H__D68326EA_D7FA_4792_AB1F_68D09533E399__INCLUDED_)
diff --git a/harbour/contrib/hbzlib/Linux/ZipPathComponent.cpp b/harbour/contrib/hbzlib/Linux/ZipPathComponent.cpp
new file mode 100644
index 0000000000..69431d104b
--- /dev/null
+++ b/harbour/contrib/hbzlib/Linux/ZipPathComponent.cpp
@@ -0,0 +1,194 @@
+////////////////////////////////////////////////////////////////////////////////
+
+// $Workfile: ZipPathComponent.cpp $
+
+// $Archive: /ZipArchive_Linux/ZipPathComponent.cpp $
+
+// $Date$ $Author$
+
+////////////////////////////////////////////////////////////////////////////////
+
+// This source file is part of the ZipArchive library source distribution and
+
+// is Copyright 2000-2003 by Tadeusz Dracz (http://www.artpol-software.com/)
+
+//
+
+// This program is free software; you can redistribute it and/or
+
+// modify it under the terms of the GNU General Public License
+
+// as published by the Free Software Foundation; either version 2
+
+// of the License, or (at your option) any later version.
+
+//
+
+// For the licensing details see the file License.txt
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+
+#include "stdafx.h"
+
+#include "zippathcomponent.h"
+
+
+
+//////////////////////////////////////////////////////////////////////
+
+// Construction/Destruction
+
+//////////////////////////////////////////////////////////////////////
+
+
+
+
+
+CZipPathComponent::~CZipPathComponent()
+
+{
+
+
+
+}
+
+
+
+void CZipPathComponent::SetFullPath(LPCTSTR lpszFullPath)
+
+{
+
+
+
+ CZipString szTempPath(lpszFullPath);
+
+ const CZipString szPrefix = _T("\\\\?\\unc\\");
+
+ int i = -1, iLen = szPrefix.GetLength();
+
+ if (iLen > szTempPath.GetLength())
+
+ iLen = szTempPath.GetLength();
+
+ CZipString szPossiblePrefix = szTempPath.Left(iLen);
+
+ szPossiblePrefix.MakeLower(); // must perform case insensitive comparison
+
+ while (++i < iLen && szPossiblePrefix[i] == szPrefix[i]);
+
+ if (i == 2 || i == 4 || i == 8) // unc path, unicode path or unc path meeting windows file name conventions
+
+ {
+
+ m_szPrefix = szTempPath.Left(i);
+
+ szTempPath = szTempPath.Mid(i);
+
+ }
+
+ else
+
+ m_szPrefix.Empty();
+
+
+
+
+
+ m_szDrive.Empty();
+
+ m_szFileTitle.Empty();
+
+ m_szDirectory.Empty();
+
+ m_szFileExt.Empty();
+
+ int p;
+
+ for (p = szTempPath.GetLength() - 1; p >= 0; p--)
+
+ if (szTempPath[p] == m_cSeparator)
+
+ break;
+
+
+
+ if (p != -1)
+
+ {
+
+ m_szDirectory = szTempPath.Left(p);
+
+ if (p == szTempPath.GetLength() - 1 )
+
+ return; // no filename present
+
+ else
+
+ p++;
+
+ }
+
+ else
+
+ p = 0;
+
+
+
+ // p points at the beginning of the filename
+
+ m_szFileTitle = szTempPath.Mid(p);
+
+ for (p = m_szFileTitle.GetLength() - 1; p >= 0; p--)
+
+ if (m_szFileTitle[p] == _T('.'))
+
+ break;
+
+
+
+ if (p != -1)
+
+ {
+
+ m_szFileExt = m_szFileTitle.Mid(p+1);
+
+ m_szFileTitle = m_szFileTitle.Left(p);
+
+ }
+
+
+
+
+
+
+
+}
+
+
+
+
+
+CZipString CZipPathComponent::GetNoDrive() const
+
+{
+
+ CZipString szPath = m_szDirectory;
+
+ CZipString szFileName = GetFileName();
+
+ if (!szFileName.IsEmpty() && !szPath.IsEmpty())
+
+ szPath += m_cSeparator;
+
+
+
+ szPath += szFileName;
+
+ return szPath;
+
+}
+
+
+
diff --git a/harbour/contrib/hbzlib/Linux/ZipPlatform.cpp b/harbour/contrib/hbzlib/Linux/ZipPlatform.cpp
new file mode 100644
index 0000000000..ebc14abab6
--- /dev/null
+++ b/harbour/contrib/hbzlib/Linux/ZipPlatform.cpp
@@ -0,0 +1,546 @@
+////////////////////////////////////////////////////////////////////////////////
+
+// $Workfile: ZipPlatform.cpp $
+
+// $Archive: /ZipArchive_Linux/ZipPlatform.cpp $
+
+// $Date$ $Author$
+
+////////////////////////////////////////////////////////////////////////////////
+
+// This source file is part of the ZipArchive library source distribution and
+
+// is Copyright 2000-2003 by Tadeusz Dracz (http://www.artpol-software.com/)
+
+//
+
+// This program is free software; you can redistribute it and/or
+
+// modify it under the terms of the GNU General Public License
+
+// as published by the Free Software Foundation; either version 2
+
+// of the License, or (at your option) any later version.
+
+//
+
+// For the licensing details see the file License.txt
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+#include "stdafx.h"
+
+#include "zipplatform.h"
+
+#include "zipfileheader.h"
+
+#include "zipexception.h"
+
+#include "zipautobuffer.h"
+
+
+
+
+
+#include
+
+
+
+
+
+
+
+#include "zippathcomponent.h"
+
+
+
+
+
+#include "zipcompatibility.h"
+
+#include
+
+#include
+
+#include
+
+#include
+
+#include
+
+#include
+
+
+
+const TCHAR CZipPathComponent::m_cSeparator = _T('/');
+
+
+
+#ifndef _UTIMBUF_DEFINED
+
+#define _utimbuf utimbuf
+
+#endif
+
+
+
+//////////////////////////////////////////////////////////////////////
+
+// Construction/Destruction
+
+//////////////////////////////////////////////////////////////////////
+
+DWORD ZipPlatform::GetDeviceFreeSpace(LPCTSTR lpszPath)
+
+{
+
+ struct statfs sStats;
+
+ if (statfs(lpszPath, &sStats) == -1)
+
+ return 0;
+
+
+
+ return sStats.f_bsize * sStats.f_bavail;
+
+}
+
+
+
+bool ZipPlatform::GetFileSize(LPCTSTR lpszFileName, DWORD& dSize)
+
+{
+
+ int f = open(lpszFileName, O_RDONLY);
+
+ if (f == -1)
+
+ return false;
+
+ int iSize = lseek(f, 0, SEEK_END);
+
+ close(f);
+
+ if (iSize == -1)
+
+ return false;
+
+ dSize = (DWORD)iSize;
+
+ return true;
+
+}
+
+
+
+CZipString ZipPlatform::GetTmpFileName(LPCTSTR lpszPath, DWORD iSizeNeeded)
+
+{
+
+ TCHAR empty[] = _T(""), prefix [] = _T("zar");
+
+ TCHAR* buf = NULL;
+
+ CZipString tempPath;
+
+ if (lpszPath)
+
+ {
+
+ // first try the user provided directory
+
+ tempPath = lpszPath;
+
+ if (ZipPlatform::GetDeviceFreeSpace(tempPath) < iSizeNeeded)
+
+ tempPath.Empty();
+
+ else
+
+ {
+
+ CZipPathComponent::AppendSeparator(tempPath);
+
+ tempPath += prefix;
+
+ tempPath += _T("XXXXXX");
+
+ TCHAR* c = mktemp(tempPath.GetBuffer(tempPath.GetLength()));
+
+ tempPath.ReleaseBuffer();
+
+ if (c)
+
+ return tempPath;
+
+ else
+
+ tempPath.Empty();
+
+ }
+
+ }
+
+
+
+
+
+ TCHAR* v = tempnam(tempPath, prefix);
+
+ tempPath = v;
+
+ free(v);
+
+
+
+ if (!tempPath.IsEmpty())
+
+ {
+
+ CZipPathComponent zpc(tempPath);
+
+ if (ZipPlatform::GetDeviceFreeSpace(zpc.GetFilePath()) < iSizeNeeded)
+
+ return empty;
+
+ return tempPath;
+
+ }
+
+ else
+
+ return empty;
+
+}
+
+
+
+bool ZipPlatform::GetCurrentDirectory(CZipString& sz)
+
+{
+
+ char* pBuf = getcwd(NULL, 0);
+
+ if (!pBuf)
+
+ return false;
+
+ sz = pBuf;
+
+ free(pBuf);
+
+ return true;
+
+}
+
+
+
+bool ZipPlatform::SetFileAttr(LPCTSTR lpFileName, DWORD uAttr)
+
+{
+
+ return chmod(lpFileName, uAttr >> 16) == 0;
+
+
+
+}
+
+
+
+bool ZipPlatform::GetFileAttr(LPCTSTR lpFileName, DWORD& uAttr)
+
+{
+
+ struct stat sStats;
+
+ if (stat(lpFileName, &sStats) == -1)
+
+ return false;
+
+ uAttr = (sStats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_IFMT)) << 16;
+
+ return true;
+
+
+
+
+
+}
+
+
+
+bool ZipPlatform::GetFileModTime(LPCTSTR lpFileName, time_t & ttime)
+
+{
+
+
+
+ struct stat st;
+
+ if (stat(lpFileName, &st) != 0)
+
+ return false;
+
+
+
+ ttime = st.st_mtime;
+
+ return ttime != -1;
+
+}
+
+
+
+bool ZipPlatform::SetFileModTime(LPCTSTR lpFileName, time_t ttime)
+
+{
+
+ struct utimbuf ub;
+
+ ub.actime = time(NULL);
+
+ ub.modtime = ttime == -1 ? time(NULL) : ttime; // if wrong file time, set it to the current
+
+ return utime(lpFileName, &ub) == 0;
+
+}
+
+
+
+
+
+bool ZipPlatform::ChangeDirectory(LPCTSTR lpDirectory)
+
+{
+
+ return chdir(lpDirectory) == 0;
+
+}
+
+int ZipPlatform::FileExists(LPCTSTR lpszName)
+
+{
+
+ struct stat st;
+
+ if (stat(lpszName, &st) != 0)
+
+ return 0;
+
+ else
+
+ {
+
+ if (S_ISDIR(st.st_mode))
+
+ return -1;
+
+ else
+
+ return 1;
+
+ }
+
+
+
+
+
+
+
+}
+
+
+
+ZIPINLINE bool ZipPlatform::IsDriveRemovable(LPCTSTR lpszFilePath)
+
+{
+
+ // not implemmented
+
+ return true;
+
+}
+
+
+
+ZIPINLINE bool ZipPlatform::SetVolLabel(LPCTSTR lpszPath, LPCTSTR lpszLabel)
+
+{
+
+ // not implemmented
+
+ return true;
+
+}
+
+
+
+ZIPINLINE void ZipPlatform::AnsiOem(CZipAutoBuffer& buffer, bool bAnsiToOem)
+
+{
+
+ // not implemmented
+
+}
+
+
+
+ZIPINLINE bool ZipPlatform::RemoveFile(LPCTSTR lpszFileName, bool bThrow)
+
+{
+
+ if (unlink(lpszFileName) != 0)
+
+ if (bThrow)
+
+ CZipException::Throw(CZipException::notRemoved, lpszFileName);
+
+ else
+
+ return false;
+
+ return true;
+
+
+
+
+
+}
+
+ZIPINLINE bool ZipPlatform::RenameFile( LPCTSTR lpszOldName, LPCTSTR lpszNewName , bool bThrow)
+
+{
+
+
+
+ if (rename(lpszOldName, lpszNewName) != 0)
+
+ if (bThrow)
+
+ CZipException::Throw(CZipException::notRenamed, lpszOldName);
+
+ else
+
+ return false;
+
+ return true;
+
+
+
+}
+
+ZIPINLINE bool ZipPlatform::IsDirectory(DWORD uAttr)
+
+{
+
+ return S_ISDIR(uAttr >> 16) != 0;
+
+}
+
+ZIPINLINE bool ZipPlatform::CreateDirectory(LPCTSTR lpDirectory)
+
+{
+
+ return mkdir(lpDirectory, S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH) == 0;
+
+
+
+}
+
+
+
+ZIPINLINE DWORD ZipPlatform::GetDefaultAttributes()
+
+{
+
+ return 0x81a40000;
+
+}
+
+
+
+ZIPINLINE DWORD ZipPlatform::GetDefaultDirAttributes()
+
+{
+
+ return 0x41ff0010;
+
+}
+
+
+
+
+
+ZIPINLINE int ZipPlatform::GetSystemID()
+
+{
+
+ return ZipCompatibility::zcUnix;
+
+}
+
+
+
+ZIPINLINE bool ZipPlatform::GetSystemCaseSensitivity()
+
+{
+
+ return true;
+
+}
+
+
+
+
+
+bool ZipPlatform::TruncateFile(int iDes, DWORD iSize)
+
+{
+
+ return ftruncate(iDes, iSize) == 0;
+
+
+
+}
+
+
+
+int ZipPlatform::OpenFile(LPCTSTR lpszFileName, UINT iMode, int iShareMode)
+
+{
+
+ return open(lpszFileName, iMode, S_IRUSR | S_IWUSR | S_IRGRP |S_IROTH );
+
+}
+
+
+
+bool ZipPlatform::FlushFile(int iDes)
+
+{
+
+ return fsync(iDes) == 0;
+
+}
+
+
+
+int ZipPlatform::GetFileSystemHandle(int iDes)
+
+{
+
+ return iDes;
+
+}
+
+
+
+
+
+
+
diff --git a/harbour/contrib/hbzlib/Makefile b/harbour/contrib/hbzlib/Makefile
deleted file mode 100644
index a00f02b6d1..0000000000
--- a/harbour/contrib/hbzlib/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# $Id$
-#
-
-
-ROOT = ../../
-
-C_SOURCES = \
- zipfile.c \
- zipfile2.c \
- zlibapi1.c \
- tzipfile.c \
- strcomp.c \
- adler32.c \
- compress.c \
- crc32.c \
- deflate.c \
- gzio.c \
- infblock.c \
- infcodes.c \
- inffast.c \
- inflate.c \
- inftrees.c \
- infutil.c \
- trees.c \
- uncompr.c \
- zutil.c \
-
-
-LIBNAME=zlib
-
-include $(TOP)$(ROOT)config/lib.cf
-
diff --git a/harbour/contrib/hbzlib/adler32.c b/harbour/contrib/hbzlib/adler32.c
deleted file mode 100644
index 39de6af360..0000000000
--- a/harbour/contrib/hbzlib/adler32.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zlib.h"
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
-#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf) DO8(buf,0); DO8(buf,8);
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
- uLong adler;
- const Bytef *buf;
- uInt len;
-{
- unsigned long s1 = adler & 0xffff;
- unsigned long s2 = (adler >> 16) & 0xffff;
- int k;
-
- if (buf == Z_NULL) return 1L;
-
- while (len > 0) {
- k = len < NMAX ? len : NMAX;
- len -= k;
- while (k >= 16) {
- DO16(buf);
- buf += 16;
- k -= 16;
- }
- if (k != 0) do {
- s1 += *buf++;
- s2 += s1;
- } while (--k);
- s1 %= BASE;
- s2 %= BASE;
- }
- return (s2 << 16) | s1;
-}
-
diff --git a/harbour/contrib/hbzlib/compress.c b/harbour/contrib/hbzlib/compress.c
deleted file mode 100644
index 1cee470913..0000000000
--- a/harbour/contrib/hbzlib/compress.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* compress.c -- compress a memory buffer
- * Copyright (C) 1995-1998 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zlib.h"
-
-/* ===========================================================================
- 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 0.1% larger than sourceLen plus
- 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-
- 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.
-*/
-int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
- int level;
-{
- z_stream stream;
- int err;
-
- stream.next_in = (Bytef*)source;
- stream.avail_in = (uInt)sourceLen;
-#ifdef MAXSEG_64K
- /* Check for source > 64K on 16-bit machine: */
- if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
-#endif
- stream.next_out = dest;
- stream.avail_out = (uInt)*destLen;
- if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
-
- stream.zalloc = (alloc_func)0;
- stream.zfree = (free_func)0;
- stream.opaque = (voidpf)0;
-
- err = deflateInit(&stream, level);
- if (err != Z_OK) return err;
-
- err = deflate(&stream, Z_FINISH);
- if (err != Z_STREAM_END) {
- deflateEnd(&stream);
- return err == Z_OK ? Z_BUF_ERROR : err;
- }
- *destLen = stream.total_out;
-
- err = deflateEnd(&stream);
- return err;
-}
-
-/* ===========================================================================
- */
-int ZEXPORT compress (dest, destLen, source, sourceLen)
- Bytef *dest;
- uLongf *destLen;
- const Bytef *source;
- uLong sourceLen;
-{
- return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
-}
diff --git a/harbour/contrib/hbzlib/crc32.c b/harbour/contrib/hbzlib/crc32.c
deleted file mode 100644
index a91101a81c..0000000000
--- a/harbour/contrib/hbzlib/crc32.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#include "zlib.h"
-
-#define local static
-
-#ifdef DYNAMIC_CRC_TABLE
-
-local int crc_table_empty = 1;
-local uLongf crc_table[256];
-local void make_crc_table OF((void));
-
-/*
- Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
- x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-
- Polynomials over GF(2) are represented in binary, one bit per coefficient,
- with the lowest powers in the most significant bit. Then adding polynomials
- is just exclusive-or, and multiplying a polynomial by x is a right shift by
- one. If we call the above polynomial p, and represent a byte as the
- polynomial q, also with the lowest power in the most significant bit (so the
- byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- where a mod b means the remainder after dividing a by b.
-
- This calculation is done using the shift-register method of multiplying and
- taking the remainder. The register is initialized to zero, and for each
- incoming bit, x^32 is added mod p to the register if the bit is a one (where
- x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- x (which is shifting right by one and adding x^32 mod p if the bit shifted
- out is a one). We start with the highest power (least significant bit) of
- q and repeat for all eight bits of q.
-
- The table is simply the CRC of all possible eight bit values. This is all
- the information needed to generate CRC's on data a byte at a time for all
- combinations of CRC register values and incoming bytes.
-*/
-local void make_crc_table()
-{
- uLong c;
- int n, k;
- uLong poly; /* polynomial exclusive-or pattern */
- /* terms of polynomial defining this crc (except x^32): */
- static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
-
- /* make exclusive-or pattern from polynomial (0xedb88320L) */
- poly = 0L;
- for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
- poly |= 1L << (31 - p[n]);
-
- for (n = 0; n < 256; n++)
- {
- c = (uLong)n;
- for (k = 0; k < 8; k++)
- c = c & 1 ? poly ^ (c >> 1) : c >> 1;
- crc_table[n] = c;
- }
- crc_table_empty = 0;
-}
-#else
-/* ========================================================================
- * Table of CRC-32's of all single-byte values (made by make_crc_table)
- */
-local const uLongf crc_table[256] = {
- 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
- 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
- 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
- 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
- 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
- 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
- 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
- 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
- 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
- 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
- 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
- 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
- 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
- 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
- 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
- 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
- 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
- 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
- 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
- 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
- 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
- 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
- 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
- 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
- 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
- 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
- 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
- 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
- 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
- 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
- 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
- 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
- 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
- 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
- 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
- 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
- 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
- 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
- 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
- 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
- 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
- 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
- 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
- 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
- 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
- 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
- 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
- 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
- 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
- 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
- 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
- 0x2d02ef8dL
-};
-#endif
-
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
-const uLongf * ZEXPORT get_crc_table()
-{
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty) make_crc_table();
-#endif
- return (const uLongf *)crc_table;
-}
-
-/* ========================================================================= */
-#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
-#define DO2(buf) DO1(buf); DO1(buf);
-#define DO4(buf) DO2(buf); DO2(buf);
-#define DO8(buf) DO4(buf); DO4(buf);
-
-/* ========================================================================= */
-uLong ZEXPORT crc32(crc, buf, len)
- uLong crc;
- const Bytef *buf;
- uInt len;
-{
- if (buf == Z_NULL) return 0L;
-#ifdef DYNAMIC_CRC_TABLE
- if (crc_table_empty)
- make_crc_table();
-#endif
- crc = crc ^ 0xffffffffL;
- while (len >= 8)
- {
- DO8(buf);
- len -= 8;
- }
- if (len) do {
- DO1(buf);
- } while (--len);
- return crc ^ 0xffffffffL;
-}
diff --git a/harbour/contrib/hbzlib/deflate.c b/harbour/contrib/hbzlib/deflate.c
deleted file mode 100644
index 25d5818e2e..0000000000
--- a/harbour/contrib/hbzlib/deflate.c
+++ /dev/null
@@ -1,1350 +0,0 @@
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-1998 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/*
- * ALGORITHM
- *
- * The "deflation" process depends on being able to identify portions
- * of the input text which are identical to earlier input (within a
- * sliding window trailing behind the input currently being processed).
- *
- * The most straightforward technique turns out to be the fastest for
- * most input files: try all possible matches and select the longest.
- * The key feature of this algorithm is that insertions into the string
- * dictionary are very simple and thus fast, and deletions are avoided
- * completely. Insertions are performed at each input character, whereas
- * string matches are performed only when the previous match ends. So it
- * is preferable to spend more time in matches to allow very fast string
- * insertions and avoid deletions. The matching algorithm for small
- * strings is inspired from that of Rabin & Karp. A brute force approach
- * is used to find longer strings when a small match has been found.
- * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- * (by Leonid Broukhis).
- * A previous version of this file used a more sophisticated algorithm
- * (by Fiala and Greene) which is guaranteed to run in linear amortized
- * time, but has a larger average cost, uses more memory and is patented.
- * However the F&G algorithm may be faster for some highly redundant
- * files if the parameter max_chain_length (described below) is too large.
- *
- * ACKNOWLEDGEMENTS
- *
- * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- * I found it in 'freeze' written by Leonid Broukhis.
- * Thanks to many people for bug reports and testing.
- *
- * REFERENCES
- *
- * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- * Available in ftp://ds.internic.net/rfc/rfc1951.txt
- *
- * A description of the Rabin and Karp algorithm is given in the book
- * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- * Fiala,E.R., and Greene,D.H.
- * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* @(#) $Id$ */
-
-#include "deflate.h"
-
-const char deflate_copyright[] =
- " deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- * Function prototypes.
- */
-typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast OF((deflate_state *s, int flush));
-local block_state deflate_slow OF((deflate_state *s, int flush));
-local void lm_init OF((deflate_state *s));
-local void putShortMSB OF((deflate_state *s, uInt b));
-local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match));
-#endif
-
-#ifdef DEBUG
-local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-# define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
-} config;
-
-local const config configuration_table[10] = {
-/* good lazy nice chain */
-/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
-/* 2 */ {4, 5, 16, 8, deflate_fast},
-/* 3 */ {4, 6, 32, 32, deflate_fast},
-
-/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-/* 5 */ {8, 16, 32, 32, deflate_slow},
-/* 6 */ {8, 16, 128, 128, deflate_slow},
-/* 7 */ {8, 32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN assertion: all calls to to UPDATE_HASH are made with consecutive
- * input characters, so that a running hash key can be computed from the
- * previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * If this file is compiled with -DFASTEST, the compression level is forced
- * to 1, and no hash chains are maintained.
- * IN assertion: all calls to to INSERT_STRING are made with consecutive
- * input characters and the first MIN_MATCH bytes of str are valid
- * (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#endif
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
- z_streamp strm;
- int level;
- const char *version;
- int stream_size;
-{
- return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
- z_streamp strm;
- int level;
- int method;
- int windowBits;
- int memLevel;
- int strategy;
- const char *version;
- int stream_size;
-{
- deflate_state *s;
- int noheader = 0;
- static const char* my_version = ZLIB_VERSION;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
- strm->msg = Z_NULL;
- if (strm->zalloc == Z_NULL) {
- strm->zalloc = zcalloc;
- strm->opaque = (voidpf)0;
- }
- if (strm->zfree == Z_NULL) strm->zfree = zcfree;
-
- if (level == Z_DEFAULT_COMPRESSION) level = 6;
-#ifdef FASTEST
- level = 1;
-#endif
-
- if (windowBits < 0) { /* undocumented feature: suppress zlib header */
- noheader = 1;
- windowBits = -windowBits;
- }
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
- return Z_STREAM_ERROR;
- }
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->noheader = noheader;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
- strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
- z_streamp strm;
- const Bytef *dictionary;
- uInt dictLength;
-{
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
-
- s = strm->state;
- strm->adler = adler32(strm->adler, dictionary, dictLength);
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
-#ifndef USE_DICT_HEAD
- dictionary += dictLength - length; /* use the tail of the dictionary */
-#endif
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- /* Insert all strings in the hash table (except for the last two bytes).
- * s->lookahead stays null, so s->ins_h will be recomputed at the next
- * call of fill_window.
- */
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
- z_streamp strm;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
-
- strm->total_in = strm->total_out = 0;
- strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
- strm->data_type = Z_UNKNOWN;
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->noheader < 0) {
- s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
- }
- s->status = s->noheader ? BUSY_STATE : INIT_STATE;
- strm->adler = 1;
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
- z_streamp strm;
- int level;
- int strategy;
-{
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
- if (level == Z_DEFAULT_COMPRESSION) {
- level = 6;
- }
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table[s->level].func;
-
- if (func != configuration_table[level].func && strm->total_in != 0) {
- /* Flush the last buffer: */
- err = deflate(strm, Z_PARTIAL_FLUSH);
- }
- if (s->level != level) {
- s->level = level;
- s->max_lazy_match = configuration_table[level].max_lazy;
- s->good_match = configuration_table[level].good_length;
- s->nice_match = configuration_table[level].nice_length;
- s->max_chain_length = configuration_table[level].max_chain;
- }
- s->strategy = strategy;
- return err;
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
- deflate_state *s;
- uInt b;
-{
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
-}
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
- z_streamp strm;
-{
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
- z_streamp strm;
- int flush;
-{
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the zlib header */
- if (s->status == INIT_STATE) {
-
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags = (s->level-1) >> 1;
-
- if (level_flags > 3) level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- strm->adler = 1L;
- }
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- /* Since avail_out is 0, deflate will be called again with
- * more output space, but possibly with both pending and
- * avail_in equal to zero. There won't be anything to do,
- * but this is not an error situation so make sure we
- * return OK instead of BUF_ERROR at next call of deflate:
- */
- s->last_flush = -1;
- return Z_OK;
- }
-
- /* Make sure there is something to do and avoid duplicate consecutive
- * flushes. For repeated and useless calls with Z_FINISH, we keep
- * returning Z_STREAM_END instead of Z_BUFF_ERROR.
- */
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = (*(configuration_table[s->level].func))(s, flush);
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
- * of deflate should use the same flush parameter to make sure
- * that the flush is complete. So we don't have to output an
- * empty block here, this will be done at next call. This also
- * ensures that for a very small output buffer, we emit at most
- * one empty block.
- */
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->noheader) return Z_STREAM_END;
-
- /* Write the zlib trailer (adler32) */
- putShortMSB(s, (uInt)(strm->adler >> 16));
- putShortMSB(s, (uInt)(strm->adler & 0xffff));
- flush_pending(strm);
- /* If avail_out is zero, the application will call deflate again
- * to flush the rest.
- */
- s->noheader = -1; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
- z_streamp strm;
-{
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE && status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- * To simplify the source, this is not supported for 16-bit MSDOS (which
- * doesn't have enough memory anyway to duplicate compression states).
- */
-int ZEXPORT deflateCopy (dest, source)
- z_streamp dest;
- z_streamp source;
-{
-#ifdef MAXSEG_64K
- return Z_STREAM_ERROR;
-#else
- deflate_state *ds;
- deflate_state *ss;
- ushf *overlay;
-
-
- if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
- return Z_STREAM_ERROR;
- }
-
- ss = source->state;
-
- *dest = *source;
-
- ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
- if (ds == Z_NULL) return Z_MEM_ERROR;
- dest->state = (struct internal_state FAR *) ds;
- *ds = *ss;
- ds->strm = dest;
-
- ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
- ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
- ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
- overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
- ds->pending_buf = (uchf *) overlay;
-
- if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
- ds->pending_buf == Z_NULL) {
- deflateEnd (dest);
- return Z_MEM_ERROR;
- }
- /* following zmemcpy do not work for 16-bit MSDOS */
- zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
- zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
- zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
- zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
- ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
- ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
- ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
- ds->l_desc.dyn_tree = ds->dyn_ltree;
- ds->d_desc.dyn_tree = ds->dyn_dtree;
- ds->bl_desc.dyn_tree = ds->bl_tree;
-
- return Z_OK;
-#endif
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read. All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
- z_streamp strm;
- Bytef *buf;
- unsigned size;
-{
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- if (!strm->state->noheader) {
- strm->adler = adler32(strm->adler, strm->next_in, len);
- }
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
- deflate_state *s;
-{
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table[s->level].max_lazy;
- s->good_match = configuration_table[s->level].good_length;
- s->nice_match = configuration_table[s->level].nice_length;
- s->max_chain_length = configuration_table[s->level].max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
-#ifdef ASMV
- match_init(); /* initialize the asm code */
-#endif
-}
-
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-#ifndef FASTEST
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2:
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-
-#else /* FASTEST */
-/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 only
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return len <= s->lookahead ? len : s->lookahead;
-}
-#endif /* FASTEST */
-#endif /* ASMV */
-
-#ifdef DEBUG
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
- deflate_state *s;
- IPos start, match;
- int length;
-{
- /* check that the match is indeed a match */
- if (zmemcmp(s->window + match,
- s->window + start, length) != EQUAL) {
- fprintf(stderr, " start %u, match %u, length %d\n",
- start, match, length);
- do {
- fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
- } while (--length != 0);
- z_error("invalid match");
- }
- if (z_verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
- do { putc(s->window[start++], stderr); } while (--length != 0);
- }
-}
-#else
-# define check_match(s, start, match, length)
-#endif
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- * At least one byte has been read, or avail_in == 0; reads are
- * performed for at least two bytes (required for the zip translate_eol
- * option -- not supported here).
- */
-local void fill_window(s)
- deflate_state *s;
-{
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if strstart == 0
- * and lookahead == 1 (input done one byte at time)
- */
- more--;
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- } else if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- /* Slide the hash table (could be avoided with 32 bit values
- at the expense of memory usage). We slide even when level == 0
- to keep the hash table consistent if we switch back to level > 0
- later. (Using level 0 permanently is not an optimal usage of
- zlib, so we don't care about this pathological case.)
- */
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
-
- /* If there was no sliding:
- * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- * more == window_size - lookahead - strstart
- * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- * => more >= window_size - 2*WSIZE + 2
- * In the BIG_MEM or MMAP case (not yet supported),
- * window_size == input_size + MIN_LOOKAHEAD &&
- * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- * Otherwise, window_size == 2*WSIZE so more >= 2.
- * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
- */
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- }
- /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
- * but this is not important since only literal bytes will be emitted.
- */
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, eof) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (eof)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
- deflate_state *s;
- int flush;
-{
- /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
- * to pending_buf_size, and each stored block has a 5 byte header:
- */
- ulg max_block_size = 0xffff;
- ulg max_start;
-
- if (max_block_size > s->pending_buf_size - 5) {
- max_block_size = s->pending_buf_size - 5;
- }
-
- /* Copy as much as possible from input to output: */
- for (;;) {
- /* Fill the window as much as possible: */
- if (s->lookahead <= 1) {
-
- Assert(s->strstart < s->w_size+MAX_DIST(s) ||
- s->block_start >= (long)s->w_size, "slide too late");
-
- fill_window(s);
- if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
- if (s->lookahead == 0) break; /* flush the current block */
- }
- Assert(s->block_start >= 0L, "block gone");
-
- s->strstart += s->lookahead;
- s->lookahead = 0;
-
- /* Emit a stored block if pending_buf will be full: */
- max_start = s->block_start + max_block_size;
- if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
- /* strstart == 0 is possible when wraparound on 16-bit machine */
- s->lookahead = (uInt)(s->strstart - max_start);
- s->strstart = (uInt)max_start;
- FLUSH_BLOCK(s, 0);
- }
- /* Flush if we may have to slide, otherwise block_start may become
- * negative and the data will be gone:
- */
- if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
- FLUSH_BLOCK(s, 0);
- }
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of the hash chain */
- int bflush; /* set if current block must be flushed */
-
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- * At this point we have always match_length < MIN_MATCH
- */
- if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY) {
- s->match_length = longest_match (s, hash_head);
- }
- /* longest_match() sets match_start */
- }
- if (s->match_length >= MIN_MATCH) {
- check_match(s, s->strstart, s->match_start, s->match_length);
-
- _tr_tally_dist(s, s->strstart - s->match_start,
- s->match_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->match_length;
-
- /* Insert new strings in the hash table only if the match length
- * is not too large. This saves time but degrades compression.
- */
-#ifndef FASTEST
- if (s->match_length <= s->max_insert_length &&
- s->lookahead >= MIN_MATCH) {
- s->match_length--; /* string at strstart already in hash table */
- do {
- s->strstart++;
- INSERT_STRING(s, s->strstart, hash_head);
- /* strstart never exceeds WSIZE-MAX_MATCH, so there are
- * always MIN_MATCH bytes ahead.
- */
- } while (--s->match_length != 0);
- s->strstart++;
- } else
-#endif
- {
- s->strstart += s->match_length;
- s->match_length = 0;
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
- Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
- * matter since it will be recomputed at next deflate call.
- */
- }
- } else {
- /* No match, output a literal byte */
- Tracevv((stderr,"%c", s->window[s->strstart]));
- _tr_tally_lit (s, s->window[s->strstart], bflush);
- s->lookahead--;
- s->strstart++;
- }
- if (bflush) FLUSH_BLOCK(s, 0);
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- /* Make sure that we always have enough lookahead, except
- * at the end of the input file. We need MAX_MATCH bytes
- * for the next match, plus MIN_MATCH bytes to insert the
- * string following the next match.
- */
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
-
- /* Insert the string window[strstart .. strstart+2] in the
- * dictionary, and set hash_head to the head of the hash chain:
- */
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- /* To simplify the code, we prevent matches with the string
- * of window index 0 (in particular we have to avoid a match
- * of the string with itself at the start of the input file).
- */
- if (s->strategy != Z_HUFFMAN_ONLY) {
- s->match_length = longest_match (s, hash_head);
- }
- /* longest_match() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
- (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR))) {
-
- /* If prev_match is also MIN_MATCH, match_start is garbage
- * but we will ignore the current match anyway.
- */
- s->match_length = MIN_MATCH-1;
- }
- }
- /* If there was a match at the previous step and the current
- * match is not better, output the previous match:
- */
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- /* Insert in hash table all strings up to the end of the match.
- * strstart-1 and strstart are already inserted. If there is not
- * enough lookahead, the last two strings are not inserted in
- * the hash table.
- */
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- /* If there was no match at the previous position, output a
- * single literal. If there was a match but the current match
- * is longer, truncate the previous match to a single literal.
- */
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
diff --git a/harbour/contrib/hbzlib/deflate.h b/harbour/contrib/hbzlib/deflate.h
deleted file mode 100644
index 962676da86..0000000000
--- a/harbour/contrib/hbzlib/deflate.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-1998 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id$ */
-
-#ifndef _DEFLATE_H
-#define _DEFLATE_H
-
-#include "zutil.h"
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS 256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES 30
-/* number of distance codes */
-
-#define BL_CODES 19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE 42
-#define BUSY_STATE 113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad dl.dad
-#define Len dl.len
-
-typedef struct static_tree_desc_s static_tree_desc;
-
-typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- int pending; /* nb of bytes in the pending buffer */
- int noheader; /* suppress zlib header and adler32 */
- Byte data_type; /* UNKNOWN, BINARY or ASCII */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
- /* Sliding window. Input bytes are read into the second half of the window,
- * and move to the first half later to keep a dictionary of at least wSize
- * bytes. With this organization, matches are limited to a distance of
- * wSize-MAX_MATCH bytes, but this ensures that IO is always
- * performed with a length multiple of the block size. Also, it limits
- * the window size to 64K, which is quite useful on MSDOS.
- * To do: use the user input buffer as sliding window.
- */
-
- ulg window_size;
- /* Actual size of window: 2*wSize, except when the user input buffer
- * is directly used as sliding window.
- */
-
- Posf *prev;
- /* Link to older string with same hash index. To limit the size of this
- * array to 64K, this link is maintained only for the last 32K strings.
- * An index in this array is thus a window index modulo 32K.
- */
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- /* Number of bits by which ins_h must be shifted at each input
- * step. It must be such that after MIN_MATCH steps, the oldest
- * byte no longer takes part in the hash key, that is:
- * hash_shift * MIN_MATCH >= hash_bits
- */
-
- long block_start;
- /* Window position at the beginning of the current output block. Gets
- * negative when the window is moved backwards.
- */
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
- /* Length of the best match at previous step. Matches not greater than this
- * are discarded. This is used in the lazy match evaluation.
- */
-
- uInt max_chain_length;
- /* To speed up deflation, hash chains are never searched beyond this
- * length. A higher limit improves compression ratio but degrades the
- * speed.
- */
-
- uInt max_lazy_match;
- /* Attempt to find a better match only when the current match is strictly
- * smaller than this value. This mechanism is used only for compression
- * levels >= 4.
- */
-# define max_insert_length max_lazy_match
- /* Insert new strings in the hash table only if the match length is not
- * greater than this length. This saves time but degrades compression.
- * max_insert_length is used only for compression levels <= 3.
- */
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
- /* Use a faster search when the previous match is longer than this */
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- /* used by trees.c: */
- /* Didn't use ct_data typedef below to supress compiler warning */
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
- /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- * The same heap array is used to build all trees.
- */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
- /* Size of match buffer for literals/lengths. There are 4 reasons for
- * limiting lit_bufsize to 64K:
- * - frequencies can be kept in 16 bit counters
- * - if compression is not successful for the first block, all input
- * data is still in the window so we can still emit a stored block even
- * when input comes from standard input. (This can also be done for
- * all blocks if lit_bufsize is not greater than 32K.)
- * - if compression is not successful for a file smaller than 64K, we can
- * even emit a stored file instead of a stored block (saving 5 bytes).
- * This is applicable only for zip (not gzip or zlib).
- * - creating new Huffman trees less frequently may not provide fast
- * adaptation to changes in the input data statistics. (Take for
- * example a binary file with poorly compressible code followed by
- * a highly compressible string table.) Smaller buffer sizes give
- * fast adaptation but have of course the overhead of transmitting
- * trees more frequently.
- * - I can't count above 4
- */
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
- /* Buffer for distances. To simplify the code, d_buf and l_buf have
- * the same number of elements. To use different lengths, an extra flag
- * array would be necessary.
- */
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
-#ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-#endif
-
- ush bi_buf;
- /* Output buffer. bits are inserted starting at the bottom (least
- * significant bits).
- */
- int bi_valid;
- /* Number of valid bits in bi_buf. All bits above the last valid bit
- * are always zero.
- */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
- /* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-
-#define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
-#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
-#endif
-
-#endif
diff --git a/harbour/contrib/hbzlib/gvmat32c.c b/harbour/contrib/hbzlib/gvmat32c.c
deleted file mode 100644
index 06d107b70c..0000000000
--- a/harbour/contrib/hbzlib/gvmat32c.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
- * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
- * File written by Gilles Vollant, by modifiying the longest_match
- * from Jean-loup Gailly in deflate.c
- * it prepare all parameters and call the assembly longest_match_gvasm
- * longest_match execute standard C code is wmask != 0x7fff
- * (assembly code is faster with a fixed wmask)
- *
- */
-
-#include "deflate.h"
-
-#undef FAR
-//#include
-
-#ifdef ASMV
-#define NIL 0
-
-#define UNALIGNED_OK
-
-
-/* if your C compiler don't add underline before function name,
- define ADD_UNDERLINE_ASMFUNC */
-#ifdef ADD_UNDERLINE_ASMFUNC
-#define longest_match_7fff _longest_match_7fff
-#define longest_match_686 _longest_match_686
-#define cpudetect32 _cpudetect32
-#endif
-
-
-
-void match_init()
-{
-}
-
-unsigned long cpudetect32();
-
-uInt longest_match_c(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-
-uInt longest_match_7fff(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-uInt longest_match_686(
- deflate_state *s,
- IPos cur_match); /* current match */
-
-uInt longest_match(
- deflate_state *s,
- IPos cur_match) /* current match */
-{
- static uInt iIsPPro=2;
-
- if ((s->w_mask == 0x7fff) && (iIsPPro==0))
- return longest_match_7fff(s,cur_match);
-
- if (iIsPPro==1)
- return longest_match_686(s,cur_match);
-
- if (iIsPPro==2)
- iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
-
- return longest_match_c(s,cur_match);
-}
-
-
-
-uInt longest_match_c(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2:
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- /* It is not necessary to compare scan[2] and match[2] since they are
- * always equal when the other bytes match, given that the hash keys
- * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
- * strstart+3, +5, ... up to strstart+257. We check for insufficient
- * lookahead only every 4th comparison; the 128th check will be made
- * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
- * necessary to put more guard bytes at the end of the window, or
- * to check more often for insufficient lookahead.
- */
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- /* The check at best_len-1 can be removed because it will be made
- * again later. (This heuristic is not always a win.)
- * It is not necessary to compare scan[2] and match[2] since they
- * are always equal when the other bytes match, given that
- * the hash keys are equal and that HASH_BITS >= 8.
- */
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
-
- /* We check for insufficient lookahead only every 8th comparison;
- * the 256th check will be made at strstart+258.
- */
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-
-#endif /* ASMV */
diff --git a/harbour/contrib/hbzlib/gzio.c b/harbour/contrib/hbzlib/gzio.c
deleted file mode 100644
index f7c336a55a..0000000000
--- a/harbour/contrib/hbzlib/gzio.c
+++ /dev/null
@@ -1,875 +0,0 @@
-/* gzio.c -- IO on .gz files
- * Copyright (C) 1995-1998 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- *
- * Compile this file with -DNO_DEFLATE to avoid the compression code.
- */
-
-/* @(#) $Id$ */
-
-#include
-
-#include "zutil.h"
-
-struct internal_state {int dummy;}; /* for buggy compilers */
-
-#ifndef Z_BUFSIZE
-# ifdef MAXSEG_64K
-# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
-# else
-# define Z_BUFSIZE 16384
-# endif
-#endif
-#ifndef Z_PRINTF_BUFSIZE
-# define Z_PRINTF_BUFSIZE 4096
-#endif
-
-#define ALLOC(size) malloc(size)
-#define TRYFREE(p) {if (p) free(p);}
-
-static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-typedef struct gz_stream {
- z_stream stream;
- int z_err; /* error code for last stream operation */
- int z_eof; /* set if end of input file */
- FILE *file; /* .gz file */
- Byte *inbuf; /* input buffer */
- Byte *outbuf; /* output buffer */
- uLong crc; /* crc32 of uncompressed data */
- char *msg; /* error message */
- char *path; /* path name for debugging only */
- int transparent; /* 1 if input file is not a .gz file */
- char mode; /* 'w' or 'r' */
- long startpos; /* start of compressed data in file (header skipped) */
-} gz_stream;
-
-
-local gzFile gz_open OF((const char *path, const char *mode, int fd));
-local int do_flush OF((gzFile file, int flush));
-local int get_byte OF((gz_stream *s));
-local void check_header OF((gz_stream *s));
-local int destroy OF((gz_stream *s));
-local void putLong OF((FILE *file, uLong x));
-local uLong getLong OF((gz_stream *s));
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing. The mode parameter
- is as in fopen ("rb" or "wb"). The file is given either by file descriptor
- or path name (if fd == -1).
- gz_open return NULL if the file could not be opened or if there was
- insufficient memory to allocate the (de)compression state; errno
- can be checked to distinguish the two cases (if errno is zero, the
- zlib error is Z_MEM_ERROR).
-*/
-local gzFile gz_open (path, mode, fd)
- const char *path;
- const char *mode;
- int fd;
-{
- int err;
- int level = Z_DEFAULT_COMPRESSION; /* compression level */
- int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
- char *p = (char*)mode;
- gz_stream *s;
- char fmode[80]; /* copy of mode, without the compression level */
- char *m = fmode;
-
- if (!path || !mode) return Z_NULL;
-
- s = (gz_stream *)ALLOC(sizeof(gz_stream));
- if (!s) return Z_NULL;
-
- s->stream.zalloc = (alloc_func)0;
- s->stream.zfree = (free_func)0;
- s->stream.opaque = (voidpf)0;
- s->stream.next_in = s->inbuf = Z_NULL;
- s->stream.next_out = s->outbuf = Z_NULL;
- s->stream.avail_in = s->stream.avail_out = 0;
- s->file = NULL;
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->crc = crc32(0L, Z_NULL, 0);
- s->msg = NULL;
- s->transparent = 0;
-
- s->path = (char*)ALLOC(strlen(path)+1);
- if (s->path == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- strcpy(s->path, path); /* do this early for debugging */
-
- s->mode = '\0';
- do {
- if (*p == 'r') s->mode = 'r';
- if (*p == 'w' || *p == 'a') s->mode = 'w';
- if (*p >= '0' && *p <= '9') {
- level = *p - '0';
- } else if (*p == 'f') {
- strategy = Z_FILTERED;
- } else if (*p == 'h') {
- strategy = Z_HUFFMAN_ONLY;
- } else {
- *m++ = *p; /* copy the mode */
- }
- } while (*p++ && m != fmode + sizeof(fmode));
- if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- err = Z_STREAM_ERROR;
-#else
- err = deflateInit2(&(s->stream), level,
- Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
- /* windowBits is passed < 0 to suppress zlib header */
-
- s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
-#endif
- if (err != Z_OK || s->outbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- } else {
- s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
-
- err = inflateInit2(&(s->stream), -MAX_WBITS);
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
- * present after the compressed stream.
- */
- if (err != Z_OK || s->inbuf == Z_NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- }
- s->stream.avail_out = Z_BUFSIZE;
-
- errno = 0;
- s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
-
- if (s->file == NULL) {
- return destroy(s), (gzFile)Z_NULL;
- }
- if (s->mode == 'w') {
- /* Write a very simple .gz header:
- */
- fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
- Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
- s->startpos = 10L;
- /* We use 10L instead of ftell(s->file) to because ftell causes an
- * fflush on some systems. This version of the library doesn't use
- * startpos anyway in write mode, so this initialization is not
- * necessary.
- */
- } else {
- check_header(s); /* skip the .gz header */
- s->startpos = (ftell(s->file) - s->stream.avail_in);
- }
-
- return (gzFile)s;
-}
-
-/* ===========================================================================
- Opens a gzip (.gz) file for reading or writing.
-*/
-gzFile ZEXPORT gzopen (path, mode)
- const char *path;
- const char *mode;
-{
- return gz_open (path, mode, -1);
-}
-
-/* ===========================================================================
- Associate a gzFile with the file descriptor fd. fd is not dup'ed here
- to mimic the behavio(u)r of fdopen.
-*/
-gzFile ZEXPORT gzdopen (fd, mode)
- int fd;
- const char *mode;
-{
- char name[20];
-
- if (fd < 0) return (gzFile)Z_NULL;
- sprintf(name, "", fd); /* for debugging */
-
- return gz_open (name, mode, fd);
-}
-
-/* ===========================================================================
- * Update the compression level and strategy
- */
-int ZEXPORT gzsetparams (file, level, strategy)
- gzFile file;
- int level;
- int strategy;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- /* Make room to allow flushing */
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
-
- return deflateParams (&(s->stream), level, strategy);
-}
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-local int get_byte(s)
- gz_stream *s;
-{
- if (s->z_eof) return EOF;
- if (s->stream.avail_in == 0) {
- errno = 0;
- s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) s->z_err = Z_ERRNO;
- return EOF;
- }
- s->stream.next_in = s->inbuf;
- }
- s->stream.avail_in--;
- return *(s->stream.next_in)++;
-}
-
-/* ===========================================================================
- Check the gzip header of a gz_stream opened for reading. Set the stream
- mode to transparent if the gzip magic header is not present; set s->err
- to Z_DATA_ERROR if the magic header is present but the rest of the header
- is incorrect.
- IN assertion: the stream s has already been created sucessfully;
- s->stream.avail_in is zero for the first time, but may be non-zero
- for concatenated .gz files.
-*/
-local void check_header(s)
- gz_stream *s;
-{
- int method; /* method byte */
- int flags; /* flags byte */
- uInt len;
- int c;
-
- /* Check the gzip magic header */
- for (len = 0; len < 2; len++) {
- c = get_byte(s);
- if (c != gz_magic[len]) {
- if (len != 0) s->stream.avail_in++, s->stream.next_in--;
- if (c != EOF) {
- s->stream.avail_in++, s->stream.next_in--;
- s->transparent = 1;
- }
- s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
- return;
- }
- }
- method = get_byte(s);
- flags = get_byte(s);
- if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
- s->z_err = Z_DATA_ERROR;
- return;
- }
-
- /* Discard time, xflags and OS code: */
- for (len = 0; len < 6; len++) (void)get_byte(s);
-
- if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
- len = (uInt)get_byte(s);
- len += ((uInt)get_byte(s))<<8;
- /* len is garbage if EOF but the loop below will quit anyway */
- while (len-- != 0 && get_byte(s) != EOF) ;
- }
- if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
- while ((c = get_byte(s)) != 0 && c != EOF) ;
- }
- if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
- for (len = 0; len < 2; len++) (void)get_byte(s);
- }
- s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
-}
-
- /* ===========================================================================
- * Cleanup then free the given gz_stream. Return a zlib error code.
- Try freeing in the reverse order of allocations.
- */
-local int destroy (s)
- gz_stream *s;
-{
- int err = Z_OK;
-
- if (!s) return Z_STREAM_ERROR;
-
- TRYFREE(s->msg);
-
- if (s->stream.state != NULL) {
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- err = Z_STREAM_ERROR;
-#else
- err = deflateEnd(&(s->stream));
-#endif
- } else if (s->mode == 'r') {
- err = inflateEnd(&(s->stream));
- }
- }
- if (s->file != NULL && fclose(s->file)) {
-#ifdef ESPIPE
- if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
-#endif
- err = Z_ERRNO;
- }
- if (s->z_err < 0) err = s->z_err;
-
- TRYFREE(s->inbuf);
- TRYFREE(s->outbuf);
- TRYFREE(s->path);
- TRYFREE(s);
- return err;
-}
-
-/* ===========================================================================
- Reads the given number of uncompressed bytes from the compressed file.
- gzread returns the number of bytes actually read (0 for end of file).
-*/
-int ZEXPORT gzread (file, buf, len)
- gzFile file;
- voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
- Bytef *start = (Bytef*)buf; /* starting point for crc computation */
- Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
-
- if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
-
- if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
- if (s->z_err == Z_STREAM_END) return 0; /* EOF */
-
- next_out = (Byte*)buf;
- s->stream.next_out = (Bytef*)buf;
- s->stream.avail_out = len;
-
- while (s->stream.avail_out != 0) {
-
- if (s->transparent) {
- /* Copy first the lookahead bytes: */
- uInt n = s->stream.avail_in;
- if (n > s->stream.avail_out) n = s->stream.avail_out;
- if (n > 0) {
- zmemcpy(s->stream.next_out, s->stream.next_in, n);
- next_out += n;
- s->stream.next_out = next_out;
- s->stream.next_in += n;
- s->stream.avail_out -= n;
- s->stream.avail_in -= n;
- }
- if (s->stream.avail_out > 0) {
- s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
- s->file);
- }
- len -= s->stream.avail_out;
- s->stream.total_in += (uLong)len;
- s->stream.total_out += (uLong)len;
- if (len == 0) s->z_eof = 1;
- return (int)len;
- }
- if (s->stream.avail_in == 0 && !s->z_eof) {
-
- errno = 0;
- s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
- if (s->stream.avail_in == 0) {
- s->z_eof = 1;
- if (ferror(s->file)) {
- s->z_err = Z_ERRNO;
- break;
- }
- }
- s->stream.next_in = s->inbuf;
- }
- s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
-
- if (s->z_err == Z_STREAM_END) {
- /* Check CRC and original size */
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
- start = s->stream.next_out;
-
- if (getLong(s) != s->crc) {
- s->z_err = Z_DATA_ERROR;
- } else {
- (void)getLong(s);
- /* The uncompressed length returned by above getlong() may
- * be different from s->stream.total_out) in case of
- * concatenated .gz files. Check for such files:
- */
- check_header(s);
- if (s->z_err == Z_OK) {
- uLong total_in = s->stream.total_in;
- uLong total_out = s->stream.total_out;
-
- inflateReset(&(s->stream));
- s->stream.total_in = total_in;
- s->stream.total_out = total_out;
- s->crc = crc32(0L, Z_NULL, 0);
- }
- }
- }
- if (s->z_err != Z_OK || s->z_eof) break;
- }
- s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
-
- return (int)(len - s->stream.avail_out);
-}
-
-
-/* ===========================================================================
- Reads one byte from the compressed file. gzgetc returns this byte
- or -1 in case of end of file or error.
-*/
-int ZEXPORT gzgetc(file)
- gzFile file;
-{
- unsigned char c;
-
- return gzread(file, &c, 1) == 1 ? c : -1;
-}
-
-
-/* ===========================================================================
- Reads bytes from the compressed file until len-1 characters are
- read, or a newline character is read and transferred to buf, or an
- end-of-file condition is encountered. The string is then terminated
- with a null character.
- gzgets returns buf, or Z_NULL in case of error.
-
- The current implementation is not optimized at all.
-*/
-char * ZEXPORT gzgets(file, buf, len)
- gzFile file;
- char *buf;
- int len;
-{
- char *b = buf;
- if (buf == Z_NULL || len <= 0) return Z_NULL;
-
- while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
- *buf = '\0';
- return b == buf && len > 0 ? Z_NULL : b;
-}
-
-
-#ifndef NO_DEFLATE
-/* ===========================================================================
- Writes the given number of uncompressed bytes into the compressed file.
- gzwrite returns the number of bytes actually written (0 in case of error).
-*/
-int ZEXPORT gzwrite (file, buf, len)
- gzFile file;
- const voidp buf;
- unsigned len;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.next_in = (Bytef*)buf;
- s->stream.avail_in = len;
-
- while (s->stream.avail_in != 0) {
-
- if (s->stream.avail_out == 0) {
-
- s->stream.next_out = s->outbuf;
- if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
- s->z_err = Z_ERRNO;
- break;
- }
- s->stream.avail_out = Z_BUFSIZE;
- }
- s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
- if (s->z_err != Z_OK) break;
- }
- s->crc = crc32(s->crc, (const Bytef *)buf, len);
-
- return (int)(len - s->stream.avail_in);
-}
-
-/* ===========================================================================
- Converts, formats, and writes the args to the compressed file under
- control of the format string, as in fprintf. gzprintf returns the number of
- uncompressed bytes actually written (0 in case of error).
-*/
-#ifdef STDC
-#include
-
-int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
-{
- char buf[Z_PRINTF_BUFSIZE];
- va_list va;
- int len;
-
- va_start(va, format);
-#ifdef HAS_vsnprintf
- (void)vsnprintf(buf, sizeof(buf), format, va);
-#else
- (void)vsprintf(buf, format, va);
-#endif
- va_end(va);
- len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
- if (len <= 0) return 0;
-
- return gzwrite(file, buf, (unsigned)len);
-}
-#else /* not ANSI C */
-
-int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
- gzFile file;
- const char *format;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
- a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
-{
- char buf[Z_PRINTF_BUFSIZE];
- int len;
-
-#ifdef HAS_snprintf
- snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-#else
- sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
- a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
-#endif
- len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
- if (len <= 0) return 0;
-
- return gzwrite(file, buf, len);
-}
-#endif
-
-/* ===========================================================================
- Writes c, converted to an unsigned char, into the compressed file.
- gzputc returns the value that was written, or -1 in case of error.
-*/
-int ZEXPORT gzputc(file, c)
- gzFile file;
- int c;
-{
- unsigned char cc = (unsigned char) c; /* required for big endian systems */
-
- return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
-}
-
-
-/* ===========================================================================
- Writes the given null-terminated string to the compressed file, excluding
- the terminating null character.
- gzputs returns the number of characters written, or -1 in case of error.
-*/
-int ZEXPORT gzputs(file, s)
- gzFile file;
- const char *s;
-{
- return gzwrite(file, (char*)s, (unsigned)strlen(s));
-}
-
-
-/* ===========================================================================
- Flushes all pending output into the compressed file. The parameter
- flush is as in the deflate() function.
-*/
-local int do_flush (file, flush)
- gzFile file;
- int flush;
-{
- uInt len;
- int done = 0;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
-
- s->stream.avail_in = 0; /* should be zero already anyway */
-
- for (;;) {
- len = Z_BUFSIZE - s->stream.avail_out;
-
- if (len != 0) {
- if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
- s->z_err = Z_ERRNO;
- return Z_ERRNO;
- }
- s->stream.next_out = s->outbuf;
- s->stream.avail_out = Z_BUFSIZE;
- }
- if (done) break;
- s->z_err = deflate(&(s->stream), flush);
-
- /* Ignore the second of two consecutive flushes: */
- if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
-
- /* deflate has finished flushing only when it hasn't used up
- * all the available space in the output buffer:
- */
- done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
-
- if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
- }
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-
-int ZEXPORT gzflush (file, flush)
- gzFile file;
- int flush;
-{
- gz_stream *s = (gz_stream*)file;
- int err = do_flush (file, flush);
-
- if (err) return err;
- fflush(s->file);
- return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
-}
-#endif /* NO_DEFLATE */
-
-/* ===========================================================================
- Sets the starting position for the next gzread or gzwrite on the given
- compressed file. The offset represents a number of bytes in the
- gzseek returns the resulting offset location as measured in bytes from
- the beginning of the uncompressed stream, or -1 in case of error.
- SEEK_END is not implemented, returns error.
- In this version of the library, gzseek can be extremely slow.
-*/
-z_off_t ZEXPORT gzseek (file, offset, whence)
- gzFile file;
- z_off_t offset;
- int whence;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || whence == SEEK_END ||
- s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
- return -1L;
- }
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- return -1L;
-#else
- if (whence == SEEK_SET) {
- offset -= s->stream.total_in;
- }
- if (offset < 0) return -1L;
-
- /* At this point, offset is the number of zero bytes to write. */
- if (s->inbuf == Z_NULL) {
- s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
- zmemzero(s->inbuf, Z_BUFSIZE);
- }
- while (offset > 0) {
- uInt size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (uInt)offset;
-
- size = gzwrite(file, s->inbuf, size);
- if (size == 0) return -1L;
-
- offset -= size;
- }
- return (z_off_t)s->stream.total_in;
-#endif
- }
- /* Rest of function is for reading only */
-
- /* compute absolute position */
- if (whence == SEEK_CUR) {
- offset += s->stream.total_out;
- }
- if (offset < 0) return -1L;
-
- if (s->transparent) {
- /* map to fseek */
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
-
- s->stream.total_in = s->stream.total_out = (uLong)offset;
- return offset;
- }
-
- /* For a negative seek, rewind and use positive seek */
- if ((uLong)offset >= s->stream.total_out) {
- offset -= s->stream.total_out;
- } else if (gzrewind(file) < 0) {
- return -1L;
- }
- /* offset is now the number of bytes to skip. */
-
- if (offset != 0 && s->outbuf == Z_NULL) {
- s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
- }
- while (offset > 0) {
- int size = Z_BUFSIZE;
- if (offset < Z_BUFSIZE) size = (int)offset;
-
- size = gzread(file, s->outbuf, (uInt)size);
- if (size <= 0) return -1L;
- offset -= size;
- }
- return (z_off_t)s->stream.total_out;
-}
-
-/* ===========================================================================
- Rewinds input file.
-*/
-int ZEXPORT gzrewind (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL || s->mode != 'r') return -1;
-
- s->z_err = Z_OK;
- s->z_eof = 0;
- s->stream.avail_in = 0;
- s->stream.next_in = s->inbuf;
- s->crc = crc32(0L, Z_NULL, 0);
-
- if (s->startpos == 0) { /* not a compressed file */
- rewind(s->file);
- return 0;
- }
-
- (void) inflateReset(&s->stream);
- return fseek(s->file, s->startpos, SEEK_SET);
-}
-
-/* ===========================================================================
- Returns the starting position for the next gzread or gzwrite on the
- given compressed file. This position represents a number of bytes in the
- uncompressed data stream.
-*/
-z_off_t ZEXPORT gztell (file)
- gzFile file;
-{
- return gzseek(file, 0L, SEEK_CUR);
-}
-
-/* ===========================================================================
- Returns 1 when EOF has previously been detected reading the given
- input stream, otherwise zero.
-*/
-int ZEXPORT gzeof (file)
- gzFile file;
-{
- gz_stream *s = (gz_stream*)file;
-
- return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
-}
-
-/* ===========================================================================
- Outputs a long in LSB order to the given file
-*/
-local void putLong (file, x)
- FILE *file;
- uLong x;
-{
- int n;
- for (n = 0; n < 4; n++) {
- fputc((int)(x & 0xff), file);
- x >>= 8;
- }
-}
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets z_err in case
- of error.
-*/
-local uLong getLong (s)
- gz_stream *s;
-{
- uLong x = (uLong)get_byte(s);
- int c;
-
- x += ((uLong)get_byte(s))<<8;
- x += ((uLong)get_byte(s))<<16;
- c = get_byte(s);
- if (c == EOF) s->z_err = Z_DATA_ERROR;
- x += ((uLong)c)<<24;
- return x;
-}
-
-/* ===========================================================================
- Flushes all pending output if necessary, closes the compressed file
- and deallocates all the (de)compression state.
-*/
-int ZEXPORT gzclose (file)
- gzFile file;
-{
- int err;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) return Z_STREAM_ERROR;
-
- if (s->mode == 'w') {
-#ifdef NO_DEFLATE
- return Z_STREAM_ERROR;
-#else
- err = do_flush (file, Z_FINISH);
- if (err != Z_OK) return destroy((gz_stream*)file);
-
- putLong (s->file, s->crc);
- putLong (s->file, s->stream.total_in);
-#endif
- }
- return destroy((gz_stream*)file);
-}
-
-/* ===========================================================================
- Returns the error message for the last error which occured on the
- given compressed file. errnum is set to zlib error number. If an
- error occured 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.
-*/
-const char* ZEXPORT gzerror (file, errnum)
- gzFile file;
- int *errnum;
-{
- char *m;
- gz_stream *s = (gz_stream*)file;
-
- if (s == NULL) {
- *errnum = Z_STREAM_ERROR;
- return (const char*)ERR_MSG(Z_STREAM_ERROR);
- }
- *errnum = s->z_err;
- if (*errnum == Z_OK) return (const char*)"";
-
- m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
-
- if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
-
- TRYFREE(s->msg);
- s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
- strcpy(s->msg, s->path);
- strcat(s->msg, ": ");
- strcat(s->msg, m);
- return (const char*)s->msg;
-}
diff --git a/harbour/contrib/hbzlib/include/ZipExport.h b/harbour/contrib/hbzlib/include/ZipExport.h
new file mode 100644
index 0000000000..08c7ef4f69
--- /dev/null
+++ b/harbour/contrib/hbzlib/include/ZipExport.h
@@ -0,0 +1,18 @@
+#if !defined (ZIP_EXPORT_H)
+#define ZIP_EXPORT_H
+
+#if defined (ZIP_HAS_DLL)
+# if (ZIP_HAS_DLL == 1)
+# if defined (ZIP_BUILD_DLL)
+# define ZIP_API __declspec (dllexport)
+# else
+# define ZIP_API __declspec (dllimport)
+# endif /* ZIP_BUILD_DLL */
+# else
+# define ZIP_API
+# endif /* ! ZIP_HAS_DLL == 1 */
+#else
+# define ZIP_API
+#endif /* ZIP_HAS_DLL */
+
+#endif /* ZIP_EXPORT_H */
diff --git a/harbour/contrib/hbzlib/include/hbz.h b/harbour/contrib/hbzlib/include/hbz.h
new file mode 100644
index 0000000000..34ef23c61f
--- /dev/null
+++ b/harbour/contrib/hbzlib/include/hbz.h
@@ -0,0 +1,84 @@
+#ifndef HB_APIZLIB_H_
+#define HB_APIZLIB_H_
+#define HB_OS_WIN_32_USED
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#ifdef __cplusplus
+#include
+extern "C" {
+#endif
+
+
+#define filePos 1
+#define Lenght 2
+#define Method 3
+#define Size 4
+#define Ratio 5
+#define Date 6
+#define Time 7
+#define Crc32 8
+#define Attr 9
+#define WRITEBUFFERSIZE (16384)
+#define MAXFILENAME (256)
+typedef struct _HB_ZIP_INTERNAL{
+int iWrite;
+int iExtract;
+int iRead;
+char * szComment;
+PHB_ITEM pItem;
+} HB_ZIP_INTERNAL,* PHB_ZIP_INTERNAL,* HB_ZIP_INTERNAL_PTR;
+#ifndef LPCTSTR
+typedef const char *LPCSTR;
+typedef LPCSTR LPCTSTR;
+#endif
+class SpanCallback : public CZipSpanCallback
+{
+ bool Callback(int iProgress)
+ {
+ PHB_ITEM pDisk=hb_itemPutNL(NULL,m_uDiskNeeded);
+ bool iReturn=true;
+ hb_vmEvalBlockV( pChangeDiskBlock, 1,pDisk );
+ hb_itemRelease(pDisk);
+ return iReturn;
+ }
+};
+
+class SpanActionCallback : public CZipActionCallback
+{
+ bool Callback(int iProgress)
+ {
+ int iReturn=1;
+ PHB_ITEM pDisk;
+ PHB_ITEM pTotal =hb_itemPutNL(NULL,m_uTotalToDo);
+ pDisk= hb_itemPutNL(NULL,m_uTotalSoFar);
+ hb_vmEvalBlockV( pProgressInfo, 2,pDisk,pTotal);
+ hb_itemRelease(pDisk);
+ hb_itemRelease(pTotal);
+ return iReturn;
+ }
+};
+
+
+class hbZip {
+public:
+BOOL bAdded;
+hbZip(){
+ bAdded=false
+};
+virtual ~hbZip();
+CZipArchive szZip;
+SpanCallback span;
+SpanActionCallback spanac;
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/harbour/contrib/hbzlib/strcomp.c b/harbour/contrib/hbzlib/include/hbzip.h
similarity index 61%
rename from harbour/contrib/hbzlib/strcomp.c
rename to harbour/contrib/hbzlib/include/hbzip.h
index f453494fe5..0da70cc170 100644
--- a/harbour/contrib/hbzlib/strcomp.c
+++ b/harbour/contrib/hbzlib/include/hbzip.h
@@ -4,9 +4,9 @@
/*
* Harbour Project source code:
- * CompressStrin() and UnCompressString() functions
+ * Header file for the Zlib API,
*
- * Copyright 2000-2001 Luiz Rafael Culik
+ * Copyright 2000 Luiz Rafael Culik
* www - http://www.harbour-project.org
*
* This program is free software; you can redistribute it and/or modify
@@ -51,42 +51,41 @@
*/
-#include "zlib.h"
-#include "hbzip2.h"
-
-#define pMaxBuffer 500000
-
-HB_FUNC(COMPRESSSTRING)
-{
- const char *szString = (const char*)hb_parc(1);
- ULONG ulLen = strlen(szString)+1;
- ULONG ulBuffLen;
- char *szBuff;
- szBuff = ( char * )hb_xalloc(ulLen+1);
- ulBuffLen = ulLen+1+pMaxBuffer;
-
- compress(szBuff, &ulBuffLen, szString, ulLen);
-
- hb_storclen(szBuff,ulBuffLen,1);
- hb_stornl(ulBuffLen,2);
- hb_xfree(szBuff);
+#ifndef HB_APIZLIB_H_
+#define HB_APIZLIB_H_
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "zip.h"
+#include "unzip.h"
+#if defined(HB_EXTERN_C)
+extern "C" {
+#endif
+#define filePos 1
+#define Lenght 2
+#define Method 3
+#define Size 4
+#define Ratio 5
+#define Date 6
+#define Time 7
+#define Crc32 8
+extern uLong hb___filetime(char *f, tm_zip *tmzip, uLong *dt);
+extern char *hb___CheckFile( char * szFile);
+extern int hb___CompressOneFile(char *szFile,char *szFiletoCompress,int iCompLevel,PHB_ITEM pBlock,BOOL bOverWrite);
+extern int hb___CompressMultipleFile(char *szFile,PHB_ITEM pArray,int iCompLevel,PHB_ITEM pBlock,BOOL bOverWrite);
+extern BOOL hb___unZipFiles(char *szFile,PHB_ITEM pBlock,BOOL bExtractPath);
+extern int hb___ExtractCurrentFile(unzFile uf,BOOL popt_extract_without_path,BOOL popt_overwrite,PHB_ITEM pBlock);
+extern void hb____ChangeFileDate(char *filename,uLong dosdate,tm_unz tmu_date);
+extern int hb___MakeDir(char *szNewDirectory);
+extern int hb___GetNumbersofFilestoUnzip(char *szFile);
+extern PHB_ITEM hb___GetFilesNamesFromZip(char *szFile,BOOL iMode);
+#if defined(HB_EXTERN_C)
}
+#endif
-HB_FUNC(UNCOMPRESSSTRING)
-{
-
- char *szString = hb_parc(1);
- ULONG ulLen = hb_parnl(2);
- ULONG ulBuffLen;
- char *szBuff;
- szBuff = ( char * )hb_xalloc(pMaxBuffer+ulLen+sizeof(ULONG));
- strcpy((char*)szBuff, "garbage");
- ulBuffLen = pMaxBuffer+ulLen;
-
- uncompress(szBuff, &ulBuffLen, szString, ulLen);
-
- hb_retclen_buffer(szBuff,ulBuffLen);
-/* hb_xfree(szBuff); */
-
-}
+#endif /* HB_APIEXT_H_ */
diff --git a/harbour/contrib/hbzlib/include/hbzip2.h b/harbour/contrib/hbzlib/include/hbzip2.h
new file mode 100644
index 0000000000..4821e125d9
--- /dev/null
+++ b/harbour/contrib/hbzlib/include/hbzip2.h
@@ -0,0 +1,128 @@
+/*
+ * $Id$
+ */
+
+/*
+ * Harbour Project source code:
+ * Header file for the Zlib API,
+ *
+ * Copyright 2000-2001 Luiz Rafael Culik
+ * www - http://www.harbour-project.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
+ *
+ * As a special exception, the Harbour Project gives permission for
+ * additional uses of the text contained in its release of Harbour.
+ *
+ * The exception is that, if you link the Harbour libraries with other
+ * files to produce an executable, this does not by itself cause the
+ * resulting executable to be covered by the GNU General Public License.
+ * Your use of that executable is in no way restricted on account of
+ * linking the Harbour library code into it.
+ *
+ * This exception does not however invalidate any other reasons why
+ * the executable file might be covered by the GNU General Public License.
+ *
+ * This exception applies only to the code released by the Harbour
+ * Project under the name Harbour. If you copy code from other
+ * Harbour Project or Free Software Foundation releases into a copy of
+ * Harbour, as the General Public License permits, the exception does
+ * not apply to the code that you add in this way. To avoid misleading
+ * anyone as to the status of such modified files, you must delete
+ * this exception notice from them.
+ *
+ * If you write modifications of your own for Harbour, it is your choice
+ * whether to permit this exception to apply to your modifications.
+ * If you do not wish that, delete this exception notice.
+ *
+ */
+
+
+#ifndef HB_APIZLIB_H_
+#define HB_APIZLIB_H_
+#define HB_OS_WIN_32_USED
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#ifdef __cplusplus
+#include
+extern "C" {
+#endif
+
+
+#define filePos 1
+#define Lenght 2
+#define Method 3
+#define Size 4
+#define Ratio 5
+#define Date 6
+#define Time 7
+#define Crc32 8
+#define Attr 9
+#define WRITEBUFFERSIZE (16384)
+#define MAXFILENAME (256)
+typedef struct _HB_ZIP_INTERNAL{
+int iWrite;
+int iExtract;
+int iRead;
+char * szComment;
+PHB_ITEM pItem;
+} HB_ZIP_INTERNAL,* PHB_ZIP_INTERNAL,* HB_ZIP_INTERNAL_PTR;
+#ifndef LPCTSTR
+typedef const char *LPCSTR;
+typedef LPCSTR LPCTSTR;
+#endif
+extern char *hb___CheckFile( char * szFile);
+extern PHB_ITEM hb___GetFilesNamesFromZip(char *szFile,BOOL iMode);
+extern void hb_____GetTime(struct tm *tz);
+extern int hb_CmpPkSpan(char *szFile,PHB_ITEM pArray,int iCompLevel,PHB_ITEM pBlock,BOOL bOverWrite,char *szPassWord,BOOL bPath,BOOL bDrive,PHB_ITEM pProgress);
+extern int hb_CmpPkSpanStd(char *szFile,char *szFiletoCompress,int iCompLevel,PHB_ITEM pBlock,BOOL bOverWrite,char *szPassWord,BOOL bPath,BOOL bDrive,PHB_ITEM pProgress);
+extern char *hb_getPassWord(char *szName);
+extern int hb___GetNumbersofFilestoUnzip(char *szFile);
+extern int hb___SetCallbackFunc(PHB_ITEM pFunc);
+extern int hb_CmpTdSpan(char *szFile,PHB_ITEM pArray,int iCompLevel,PHB_ITEM pBlock,BOOL bOverWrite,char *szPassWord,PHB_ITEM pDiskBlock,int iSpanSize ,BOOL bPath ,BOOL bDrive,PHB_ITEM pProgress);
+
+extern int hb_CompressFile(char *szFile,PHB_ITEM pArray,int iCompLevel,PHB_ITEM pBlock,BOOL bOverWrite,char *szPassWord,BOOL bPath,BOOL bDrive,PHB_ITEM pProgress);
+extern int hb_CompressFileStd(char *szFile,char *szFiletoCompress,int iCompLevel,PHB_ITEM pBlock,BOOL bOverWrite,char *szPassWord,BOOL bPath,BOOL bDrive,PHB_ITEM pProgress);
+extern int hb_CmpTdSpanStd(char *szFile,char * szFiletoCompress,int iCompLevel,PHB_ITEM pBlock,BOOL bOverWrite,char *szPassWord,PHB_ITEM pDiskBlock,int iSpanSize,BOOL bPath,BOOL bDrive,PHB_ITEM pProgress);
+extern int hb_UnzipAll(char *szFile,PHB_ITEM pBlock,BOOL bWithPath,char *szPassWord,char *szPath,PHB_ITEM pDiskBlock,PHB_ITEM pProgress);
+extern int hb_UnzipOne(char *szFile,PHB_ITEM pBlock,BOOL bWithPath,char *szPassWord,char *szPath,char *szFiletoExtract,PHB_ITEM pProgress);
+extern int hb_UnzipSel(char *szFile,PHB_ITEM pBlock,BOOL bWithPath,char *szPassWord,char *szPath,PHB_ITEM pArray,PHB_ITEM pProgress);
+extern int hb_UnzipOneIndex(char *szFile,PHB_ITEM pBlock,BOOL bWithPath,char *szPassWord,char *szPath,int uiCount,PHB_ITEM pProgress);
+extern int hb_UnzipSelIndex(char *szFile,PHB_ITEM pBlock,BOOL bWithPath,char *szPassWord,char *szPath,PHB_ITEM pSelArray,PHB_ITEM pProgress);
+extern int hb_DeleteOne(char *szFile,char *szFiletoDelete);
+extern int hb_DeleteSel(char *szFile,PHB_ITEM pArray,BOOL bCase);
+extern int hb_DeleteOneIndex(char *szFile,int uiCount);
+extern int hb_TestForPKS(char *szFile);
+extern void hb_SetZipBuff(int a,int b,int c);
+extern void hb_SetZipComment(char *szComment);
+extern const char *hb_GetZipComment(char *szFile);
+extern BOOL hb_IsPassWord(char *szName);
+extern unsigned long GetCurrentFileSize( LPCTSTR szFile);
+extern BOOL hb_SaveZipFileFromMemory(char *szFile);
+extern BOOL hb_CreateZipInMemory(char *szFileToCompress,char *szFile);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* HB_APIEXT_H_ */
diff --git a/harbour/contrib/hbzlib/include/resource.h b/harbour/contrib/hbzlib/include/resource.h
new file mode 100644
index 0000000000..6cf0c78db2
--- /dev/null
+++ b/harbour/contrib/hbzlib/include/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by version.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1000
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/harbour/contrib/hbzlib/stdafx.h b/harbour/contrib/hbzlib/include/stdafx.h
similarity index 69%
rename from harbour/contrib/hbzlib/stdafx.h
rename to harbour/contrib/hbzlib/include/stdafx.h
index fb9046fcbc..bd28a8dae6 100644
--- a/harbour/contrib/hbzlib/stdafx.h
+++ b/harbour/contrib/hbzlib/include/stdafx.h
@@ -1,9 +1,11 @@
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-// Part of the ZipArchive library
-//
-// Copyright (C) 2000 - 2001 Tadeusz Dracz.
+////////////////////////////////////////////////////////////////////////////////
+// $Workfile: stdafx.h $
+// $Archive: /ZipArchive_STL/stdafx.h $
+// $Date$ $Author$
+////////////////////////////////////////////////////////////////////////////////
+// This source file is part of the ZipArchive library source distribution and
+// is Copyright 2000-2003 by Tadeusz Dracz (http://www.artpol-software.com/)
+//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
@@ -15,12 +17,13 @@
#if !defined(AFX_STDAFX_H__926F70F4_1B34_49AA_9532_498E8D2F3495__INCLUDED_)
#define AFX_STDAFX_H__926F70F4_1B34_49AA_9532_498E8D2F3495__INCLUDED_
-#ifdef __BORLANDC__
-#define ZIPINLINE
+#if (_MSC_VER < 1300) && !defined (__BORLANDC__) && !defined (__GNUC__)
+ #define ZIPINLINE inline
#else
-#define ZIPINLINE inline
+ #define ZIPINLINE
#endif
+
#define ZIP_ARCHIVE_STL
#if _MSC_VER > 1000
@@ -28,6 +31,7 @@
//because of STL
#pragma warning (disable : 4710) // 'function' : function not inlined
#pragma warning (disable : 4514) // unreferenced inline/local function has been removed
+ #pragma warning (disable:4786) // 'identifier' : identifier was truncated to 'number' characters in the debug information
#endif // _MSC_VER > 1000
@@ -49,11 +53,21 @@
typedef int HFILE;
typedef void* HANDLE;
typedef unsigned long DWORD;
+ typedef long LONG;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int UINT;
+ #ifndef FALSE
+ #define FALSE (int)0
+ #endif
+
+ #ifndef TRUE
+ #define TRUE (int)1
+ #endif
+
+
typedef unsigned short WCHAR; // wc, 16-bit UNICODE character
typedef const WCHAR *LPCWSTR;
typedef const char *LPCSTR;
@@ -74,16 +88,11 @@
#else
- #include
- #include
+ #include
+ #include
#ifndef STRICT
#define STRICT
#endif
- #include
- # define ZEXPORT __declspec(dllexport) WINAPI
- # define ZEXPORTRVA __declspec(dllexport) WINAPIV
-
-
#endif // #ifndef _WIN32
#ifndef ASSERT
@@ -103,6 +112,14 @@
#define TRACE
#endif
+#if _MSC_VER >= 1300
+ #define ZIP_ULONGLONG ULONGLONG
+ #define ZIP_LONGLONG LONGLONG
+#else
+ #define ZIP_ULONGLONG DWORD
+ #define ZIP_LONGLONG LONG
+#endif
+
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
diff --git a/harbour/contrib/hbzlib/unzip.h b/harbour/contrib/hbzlib/include/unzip.h
similarity index 95%
rename from harbour/contrib/hbzlib/unzip.h
rename to harbour/contrib/hbzlib/include/unzip.h
index de7a92c6ce..89fef3fd7a 100644
--- a/harbour/contrib/hbzlib/unzip.h
+++ b/harbour/contrib/hbzlib/include/unzip.h
@@ -1,4 +1,4 @@
-/* unzip.h -- IO for uncompress .zip files using zlib
+/* unzip.h -- IO for uncompress .zip files using zlib
Version 0.15 beta, Mar 19th, 1998,
Copyright (C) 1998 Gilles Vollant
@@ -33,7 +33,7 @@
*/
-/* for more info about .ZIP format, see
+/* for more info about .ZIP format, see
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
PkWare has also a specification at :
ftp://ftp.pkware.com/probdesc.zip */
@@ -41,18 +41,19 @@
#ifndef _unz_H
#define _unz_H
-#ifdef __cplusplus
-extern "C" {
+#ifndef _HBCOMPRESS_H
+#include "hbcomprs.h"
#endif
-#ifndef _ZLIB_H
-#include "zlib.h"
+
+#ifdef __cplusplus
+extern "C" {
#endif
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
/* like the STRICT of WIN32, we define a pointer that cannot be converted
from (void*) without cast */
-typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef struct TagunzFile__ { int unused; } unzFile__;
typedef unzFile__ *unzFile;
#else
typedef voidp unzFile;
@@ -69,7 +70,7 @@ typedef voidp unzFile;
#define UNZ_CRCERROR (-105)
/* tm_unz contain date/time info */
-typedef struct tm_unz_s
+typedef struct tm_unz_s
{
uInt tm_sec; /* seconds after the minute - [0,59] */
uInt tm_min; /* minutes after the hour - [0,59] */
@@ -98,8 +99,8 @@ typedef struct unz_file_info_s
uLong compression_method; /* compression method 2 bytes */
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
uLong crc; /* crc-32 4 bytes */
- uLong compressed_size; /* compressed size 4 bytes */
- uLong uncompressed_size; /* uncompressed size 4 bytes */
+ uLong compressed_size; /* compressed size 4 bytes */
+ uLong uncompressed_size; /* uncompressed size 4 bytes */
uLong size_filename; /* filename length 2 bytes */
uLong size_file_extra; /* extra field length 2 bytes */
uLong size_file_comment; /* file comment length 2 bytes */
@@ -175,7 +176,7 @@ extern int ZEXPORT unzGoToNextFile OF((unzFile file));
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
-extern int ZEXPORT unzLocateFile OF((unzFile file,
+extern int ZEXPORT unzLocateFile OF((unzFile file,
const char *szFileName,
int iCaseSensitivity));
/*
@@ -226,8 +227,8 @@ extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
-
-extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
voidp buf,
unsigned len));
/*
@@ -248,7 +249,7 @@ extern z_off_t ZEXPORT unztell OF((unzFile file));
extern int ZEXPORT unzeof OF((unzFile file));
/*
- return 1 if the end of file was reached, 0 elsewhere
+ return 1 if the end of file was reached, 0 elsewhere
*/
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
@@ -263,7 +264,7 @@ extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
if buf!=NULL, len is the size of the buffer, the extra header is copied in
buf.
- the return value is the number of bytes copied in buf, or (if <0)
+ the return value is the number of bytes copied in buf, or (if <0)
the error code
*/
#ifdef __cplusplus
diff --git a/harbour/contrib/hbzlib/zconf.h b/harbour/contrib/hbzlib/include/zconf.h
similarity index 94%
rename from harbour/contrib/hbzlib/zconf.h
rename to harbour/contrib/hbzlib/include/zconf.h
index 6d450fc793..9fcacbe06f 100644
--- a/harbour/contrib/hbzlib/zconf.h
+++ b/harbour/contrib/hbzlib/include/zconf.h
@@ -1,5 +1,5 @@
/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -8,6 +8,19 @@
#ifndef _ZCONF_H
#define _ZCONF_H
+/*
+#if _MSC_VER > 1000
+ #pragma warning (disable : 4131)
+ #pragma warning (disable : 4115)
+ #pragma warning (disable : 4127)
+ #pragma warning (disable : 4100)
+ #pragma warning (disable : 4244)
+ #pragma warning (disable : 4702)
+ #pragma warning (disable : 4206)
+#endif // _MSC_VER > 1000
+*/
+
+
/*
* 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.
@@ -130,13 +143,23 @@
/* Type declarations */
-#ifndef OF /* function prototypes */
+/* function prototypes */
+
+#ifdef OF
+#undef OF
+#endif
+
+/*
+#ifndef OF
# 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).
diff --git a/harbour/contrib/hbzlib/zip.h b/harbour/contrib/hbzlib/include/zip.h
similarity index 95%
rename from harbour/contrib/hbzlib/zip.h
rename to harbour/contrib/hbzlib/include/zip.h
index 8426eecc3c..9310860a79 100644
--- a/harbour/contrib/hbzlib/zip.h
+++ b/harbour/contrib/hbzlib/include/zip.h
@@ -1,4 +1,4 @@
-/* zip.h -- IO for compress .zip files using zlib
+/* zip.h -- IO for compress .zip files using zlib
Version 0.15 alpha, Mar 19th, 1998,
Copyright (C) 1998 Gilles Vollant
@@ -36,7 +36,7 @@
*/
-/* for more info about .ZIP format, see
+/* for more info about .ZIP format, see
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
PkWare has also a specification at :
ftp://ftp.pkware.com/probdesc.zip
@@ -44,18 +44,21 @@
#ifndef _zip_H
#define _zip_H
+
+
+#ifndef _HBCOMPRESS_H
+#include "hbcomprs.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
-#ifndef _ZLIB_H
-#include "zlib.h"
-#endif
#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
/* like the STRICT of WIN32, we define a pointer that cannot be converted
from (void*) without cast */
-typedef struct TagzipFile__ { int unused; } zipFile__;
+typedef struct TagzipFile__ { int unused; } zipFile__;
typedef zipFile__ *zipFile;
#else
typedef voidp zipFile;
@@ -67,7 +70,7 @@ typedef voidp zipFile;
#define ZIP_INTERNALERROR (-104)
/* tm_zip contain date/time info */
-typedef struct tm_zip_s
+typedef struct tm_zip_s
{
uInt tm_sec; /* seconds after the minute - [0,59] */
uInt tm_min; /* minutes after the hour - [0,59] */
diff --git a/harbour/contrib/hbzlib/include/zipabstractfile.h b/harbour/contrib/hbzlib/include/zipabstractfile.h
new file mode 100644
index 0000000000..8c9097b262
--- /dev/null
+++ b/harbour/contrib/hbzlib/include/zipabstractfile.h
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////
+// $Workfile: ZipAbstractFile.h $
+// $Archive: /ZipArchive/ZipAbstractFile.h $
+// $Date$ $Author$
+////////////////////////////////////////////////////////////////////////////////
+// This source file is part of the ZipArchive library source distribution and
+// is Copyright 2000-2003 by Tadeusz Dracz (http://www.artpol-software.com/)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// For the licensing details see the file License.txt
+////////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_ZIPABSTRACTFILE_H__46F247DE_21A6_4D12_AF64_B5A6B3CF4D57__INCLUDED_)
+#define AFX_ZIPABSTRACTFILE_H__46F247DE_21A6_4D12_AF64_B5A6B3CF4D57__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+#include "ZipExport.h"
+#include "zipstring.h"
+
+class ZIP_API CZipAbstractFile
+{
+public:
+
+ enum { begin = SEEK_SET, // 0
+ current = SEEK_CUR, // 1
+ end = SEEK_END // 2
+ };
+ CZipAbstractFile(){}
+ virtual bool Open(LPCTSTR , UINT , bool ){return true;}
+ virtual void Close() = 0;
+ virtual void Flush() = 0;
+ virtual ZIP_ULONGLONG GetPosition() const = 0;
+ virtual ZIP_ULONGLONG Seek(ZIP_LONGLONG lOff, int nFrom) = 0;
+ virtual ZIP_ULONGLONG GetLength() const = 0;
+ virtual void SetLength(ZIP_ULONGLONG nNewLen) = 0;
+ virtual ZIP_ULONGLONG SeekToBegin(){return Seek(0, begin);}
+ virtual ZIP_ULONGLONG SeekToEnd(){return Seek(0, end);}
+ virtual CZipString GetFilePath() const = 0;
+ virtual UINT Read(void *lpBuf, UINT nCount) = 0;
+ virtual void Write(const void* lpBuf, UINT nCount) = 0;
+ virtual bool IsClosed() const = 0;
+ virtual ~CZipAbstractFile(){};
+
+};
+
+
+
+#endif // !defined(AFX_ZIPABSTRACTFILE_H__46F247DE_21A6_4D12_AF64_B5A6B3CF4D57__INCLUDED_)
diff --git a/harbour/contrib/hbzlib/include/ziparchive.h b/harbour/contrib/hbzlib/include/ziparchive.h
new file mode 100644
index 0000000000..23402203e0
--- /dev/null
+++ b/harbour/contrib/hbzlib/include/ziparchive.h
@@ -0,0 +1,2052 @@
+///////////////////////////////////////////////////////////////////////////////
+// $Workfile: ZipArchive.h $
+// $Archive: /ZipArchive/ZipArchive.h $
+// $Date$ $Author$
+////////////////////////////////////////////////////////////////////////////////
+// This source file is part of the ZipArchive library source distribution and
+// is Copyright 2000-2003 by Tadeusz Dracz (http://www.artpol-software.com/)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// For the licensing details see the file License.txt
+//
+// Check the site http://www.artpol-software.com for the updated version of the library.
+////////////////////////////////////////////////////////////////////////////////
+//
+// The following information files are distributed along with this library:
+// License.txt - licensing information
+// gpl.txt - General Public License text
+// Readme.txt - general information
+// ChangeLog.txt - revision history
+// faq.txt - frequently asked questions
+// Appnote.txt - details on the zip format
+// ( also available at ftp://ftp.pkware.com/appnote.zip)
+//
+//
+
+
+
+/**
+* \file ZipArchive.h
+* Interface for the CZipArchive class.
+*
+*/
+
+#if !defined(AFX_ZIPARCHIVE_H__A7F528A6_1872_4071_BE66_D56CC2DDE0E6__INCLUDED_)
+#define AFX_ZIPARCHIVE_H__A7F528A6_1872_4071_BE66_D56CC2DDE0E6__INCLUDED_
+
+/**
+ \namespace ziparchv
+ A helper namespace.
+ \par Members
+ - CZipFileMapping
+
+*/
+
+
+
+
+/**
+ \struct CZipFileMapping ZipFileMapping.h
+
+ Maps a file to the memory. A system-specific implementation.
+ Stored in ziparchv namespace.
+
+ \c #include "ZipFileMapping.h"
+*/
+
+
+// to ensure that the correct files are copied
+// (see "Compatibility" chapter in the documentation).
+// Rebuild the project after copying the files.
+#ifdef ZIP_ARCHIVE_MFC_PROJ
+ #ifndef ZIP_ARCHIVE_MFC
+ #error You need to copy files from the MFC subdirectory\
+ to the ZipArchive root directory and rebuild the project
+ #endif
+#elif defined ZIP_ARCHIVE_STL_PROJ
+ #ifndef ZIP_ARCHIVE_STL
+ #error You need to copy files from the STL subdirectory\
+ to the ZipArchive root directory and rebuild the project
+ #endif
+#endif //
+
+#if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL)
+ #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class
+ #pragma warning( disable : 4275 ) // non dll-interface class used as base for dll-interface
+#endif
+
+
+//#ifdef __cplusplus
+//extern "C" {
+//#endif
+#ifndef _HBCOMPRESS_H
+#include "hbcomprs.h"
+#endif
+//#ifdef __cplusplus
+//}
+//#endif
+
+
+#include "zipexception.h"
+#include "zipautobuffer.h"
+#include "zipcentraldir.h"
+#include "zipstorage.h"
+#include "zippathcomponent.h"
+#include "zipstring.h"
+#include "ZipExport.h"
+
+
+/**
+ Structure used as a parameter in CZipArchive::AddNewFile(CZipAddNewFileInfo& );
+ Use one of constructors provided and then adjust the member variables that are
+ set to default values by #Defaults method.
+*/
+struct ZIP_API CZipAddNewFileInfo
+{
+ CZipAddNewFileInfo(LPCTSTR lpszFilePath, bool bFullPath = true)
+ : m_szFilePath(lpszFilePath),m_bFullPath(bFullPath)
+ {
+ m_pFile = NULL;
+ Defaults();
+ }
+ CZipAddNewFileInfo(LPCTSTR lpszFilePath, LPCTSTR lpszFileNameInZip)
+ : m_szFilePath(lpszFilePath), m_szFileNameInZip(lpszFileNameInZip)
+ {
+ m_pFile = NULL;
+ Defaults();
+ }
+ CZipAddNewFileInfo(CZipAbstractFile* pFile, LPCTSTR lpszFileNameInZip)
+ : m_pFile(pFile), m_szFileNameInZip(lpszFileNameInZip)
+ {
+ Defaults();
+ }
+ /**
+ the full path to the file to be added; if it is empty you need to set #m_pFile
+ */
+ CZipString m_szFilePath;
+
+ /**
+ the file name that will be stored in the archive (if the file is a directory,
+ there is a path separator automatically added at the end); #SetRootPath
+ function has no effect on this parameter
+ */
+ CZipString m_szFileNameInZip;
+
+ /**
+ It has only the meaning when #m_szFileNameInZip is not specified and #m_szFilePath is not empty.
+
+ - if \c true, include full path of the file inside the archive (even if #m_szRootPath is set)
+
+ - if \c false only the filename without a path is stored in the archive
+
+ in this case if #m_szRootPath is set previously with #SetRootPath
+ and if the beginning of #m_szFilePath equals #m_szRootPath
+ then the filename is set to the remaining part of m_szFilePath
+ (you can say to m_lpszFilePath minus #m_szRootPath)
+ */
+ bool m_bFullPath;
+
+ /**
+ the compression level, see #OpenNewFile
+ */
+ int m_iComprLevel;
+
+ /**
+ the smartness level of of the library; can be one or more #Smartness
+ values (you can OR them);
+ if zipsmCheckForEff is specified and due to it the file needs to be
+ reinserted into the archive without a compression and the callback
+ functor is specified, the callback functor's method Callback is called with the first argument set to
+ DWORD (-1) (you need to remember the last argument if you need the size of the file)
+ */
+ int m_iSmartLevel;
+
+ /**
+ the index of the existing file in the archive to be replaced by the file being added (the new file
+ goes into the same physical place as the old file - the archive may of course grow or shrink as a result)
+
+- >= 0 the index of the file to be replaced
+- -1 do not replace any file and add the new file at the end of the archive (default)
+- -2 if the new file has the same name as a file already in the archive then replace it or add at the end of the archive if it's filename is unique; it uses CZipArchive::FindFile with
+ the arguments \e iCaseSensitive and \e bFileNameOnly set to default values
+
+ \note
+ - you replace files in disk-spanning archives (i.e. use a value different from -1)
+ - if the space size taken by the old file is different from the space size needed by the new file, the callback is called while moving data (see CZipArchive::cbReplace)
+ - this replaces the file physically, so no information from the file being replaced is retained (such as attributes, modification time, etc.)
+ - if you use an invalid index, the function will fail; if you specify the last file in the archive to be replaced, it'll be removed and the usual action taken
+ - the new file encryption does not depend on the old file encryption but only on the current password settings (see CZipArchive::SetPassword)
+ - if #m_iComprLevel is not 0 then a temporary archive is created in the temporary directory
+ (see CZipArchive::SetTempPath) or in the memory (if you use CZipArchive::zipsmMemoryFlag in #m_iSmartLevel)
+ - the most complicated scenario is when you try to replace the file and use CZipArchive::zipsmCheckForEff flag in #m_iSmartLevel and the file compression proves to be
+ inefficient (you can use the sample application \e ZipArc to observe the following process):
+ - first you get CZipArchive::cbAdd callback - the file is being compressed to a temporary archive,
+ - then the file compression proves to be inefficient and the file needs to be stored instead of compressed,
+ but first the space inside archive must be adjusted to fit the file being added in the place of file being replaced - you get CZipArchive::cbReplace,
+ - then, at the end, the file is being stored - you get CZipArchive::cbAddStore callback
+
+ \see SetAdvanced
+ \see CZipArchive::WillBeDuplicated
+ */
+ int m_iReplaceIndex;
+
+ /**
+ the size of the buffer used while file operations
+ */
+ unsigned long m_nBufSize;
+
+ /**
+ instead of from a physical file, the data for compression is taken from the CZipAbstractFile object (e.g. from CZipMemFile)
+
+ \note
+ - you have to leave #m_szFilePath empty if you set #m_pFile to not NULL
+ - the time of the file in zip is set to the current time, and the attributes to the default
+ file attributes (depending on the system)
+ - you cannot add directories this way
+ */
+ CZipAbstractFile* m_pFile;
+
+ /**
+ Set default values for #m_iSmartLevel, #m_iReplaceIndex, #m_nBufSize and #m_iComprLevel
+ */
+ void Defaults();
+};
+
+
+/**
+ The representation of the zip archive file.
+ This class provides all the operations on the zip archive.
+
+*/
+class ZIP_API CZipArchive
+{
+
+public:
+ /**
+ The purpose of this structure is to hold the data that allow communication
+ with the zlib library
+ */
+ struct ZIP_API CZipInternalInfo
+ {
+
+ CZipInternalInfo()
+ {
+ m_iBufferSize = 65536;
+ }
+ virtual ~CZipInternalInfo(){}
+
+ /**
+ Allocate internal buffer of m_iBufferSize size
+ */
+ void Init()
+ {
+ m_pBuffer.Allocate(m_iBufferSize);
+ }
+ void ReleaseBuf()
+ {
+ m_pBuffer.Release();
+ }
+ z_stream m_stream; ///< zlib library data stream
+ DWORD m_uUncomprLeft; ///< bytes left to uncompress
+ DWORD m_uComprLeft; ///< bytes left to decompress
+ DWORD m_uCrc32; ///< crc32 file control value
+
+ /**
+ The size of the buffer used in decompressing data.
+ Set before opening the archive.
+ It is usually set with CZipArchive::SetAdvanced
+ (specify this value as the second argument).
+ \see CZipArchive::SetAdvanced
+ */
+ DWORD m_iBufferSize;
+
+ /**
+ This buffer caches data during compression and decompression.
+ */
+ CZipAutoBuffer m_pBuffer;
+ };
+
+ CZipArchive();
+ virtual ~CZipArchive();
+
+/**
+ In non-UNICODE version just copy \e szSingle to \e szWide.
+ In UNICODE version works the same way as ZipPlatform::SingleToWide
+ \param szSingle
+ \param szWide
+
+ \return (in non-UNICODE version the number of characters copied)
+ \see ZipPlatform::SingleToWide
+*/
+ static int SingleToWide(const CZipAutoBuffer &szSingle, CZipString& szWide);
+
+/**
+ In non-UNICODE version just copy \e lpWide to \e szSingle.
+ In UNICODE version works the same way as ZipPlatform::WideToSingle
+ \param lpWide
+ \param szSingle
+ \return (in non-UNICODE version the number of characters copied)
+ \see ZipPlatform::WideToSingle
+
+*/
+ static int WideToSingle(LPCTSTR lpWide, CZipAutoBuffer &szSingle);
+
+
+/**
+ Set the password for the file to be opened or created.
+ Use this method BEFORE opening or adding a file, but AFTER opening an archive
+ \param lpszPassword
+ set it to NULL to clear password
+ \return \c false if the password contains ASCII characters
+ with values 128 or higher or the file inside archive is opened
+
+*/
+ bool SetPassword(LPCTSTR lpszPassword = NULL);
+
+/**
+ \return the current archive password or an empty string if there is no password
+*/
+ CZipString GetPassword()const ;
+
+/**
+ Set the buffer sizes. No buffer can be set smaller than 1024.
+ Use this method before opening the archive. The optimal size for
+ the write buffer in the disk spanning archive is the size of the volume.
+
+ \param iWriteBuffer
+ the write cache size used
+ \see CZipStorage::m_iWriteBufferSize
+ \param iGeneralBuffer
+ buffer used in extracting, compressing, deleting, getting (#GetFromArchive) files, renaming and replacing
+ \see CZipInternalInfo::m_iBufferSize
+ \param iSearchBuffer
+ the buffer used in searching for the central dir
+ \see CZipCentralDir::m_iBufferSize
+ \see GetAdvanced
+*/
+ void SetAdvanced(int iWriteBuffer = 65536, int iGeneralBuffer = 65536, int iSearchBuffer = 32768);
+
+ /**
+ retreive buffer size as set by #SetAdvanced
+ */
+ void GetAdvanced(int* piWriteBuffer = NULL, int* piGeneralBuffer = NULL, int* piSearchBuffer= NULL)
+ {
+ if (piWriteBuffer)
+ *piWriteBuffer = m_storage.m_iWriteBufferSize;
+ if (piGeneralBuffer)
+ *piGeneralBuffer = m_info.m_iBufferSize;
+ if (piSearchBuffer)
+ *piSearchBuffer = m_centralDir.m_iBufferSize;
+ }
+
+ /**
+ Enum values used as \e iWhich parameter in #SetCallback function.
+ You can assign several values to the same functor (OR them)
+ \see CZipActionCallback
+ */
+ enum CallbackType
+ {
+ cbNothing = 0x0000, ///< you can use it for your own purposes
+ cbAdd = 0x0001, ///< called when adding a file with one of #AddNewFile functions
+ cbAddTmp = 0x0002, ///< called while adding a file (only on a disk-spanning archive) when the smartness level contains CZipArchive::zipsmCheckForEff or CZipArchive::zipsmCheckForEffInMem
+ ///< and if just compressed file is being moved from a temporary place (file or memory) to the archive
+ cbAddStore = 0x0004, ///< called while adding a file and if it's compressing has proven to be inefficient and it is now being stored (instead of compressed) in the archive;
+ ///< smartness level must contain CZipArchive::zipsmCheckForEff or CZipArchive::zipsmCheckForEffInMem; the archive can be disk-spanning or not
+
+ cbExtract = 0x0008, ///< called when extracting a file with one of #ExtractFile functions
+
+ cbDeleteCnt = 0x0010, ///< called before the actual deletion takes place and the map of holes and continuous areas is being created (it safe to break it by returning \c false from the callback method)
+ cbDelete = 0x0020, ///< called when moving data while deleting file(s) with function #DeleteFile or one of #DeleteFiles functions
+
+ cbTest = 0x0040, ///< called when testing a file with #TestFile function
+ cbSave = 0x0080, ///< called when saving the central directory with CZipCentralDir::Write (usually on close or flush); it is safe to break on non-disk spanning archive - the saved part of
+ ///< the central directory will be removed from disk
+ cbGetFromArchive
+ = 0x0100, ///< called when using one of #GetFromArchive methods
+ cbRename = 0x0200, ///< called when during the renaming a file there is a need to make less or more space for the new filename
+ cbReplace = 0x0400, ///< called when moving data while replacing files to make less or more space for the new file
+ cbNextValue = 0x0800, ///< for CZipActionCallback overrides and user defined callbacks
+
+
+ cbSubActions= cbAddTmp | cbAddStore | cbDeleteCnt | cbReplace, ///< sub actions - they are part of bigger actions (#cbAddTmp | #cbAddStore | #cbDeleteCnt | #cbReplace)
+ cbActions = cbAdd | cbExtract | cbDelete | cbTest | cbSave | cbGetFromArchive | cbRename, ///< main actions (#cbAdd | #cbExtract | #cbDelete | #cbTest | #cbSave | #cbGetFromArchive | #cbRename)
+ cbAll = cbActions | cbSubActions ///< assign all callbacks to the same functor
+ };
+
+
+ /**
+
+ Set callback functors for the following operations on the zip archive: adding, extracting, testing or deleting files.
+ See \ref sectCallb information on how to use functors.
+ \param pCallback
+ the address of the functional object which class is derived from CZipActionCallback
+ (you need to override member function CZipCallback::Callback in the derived class)
+ Set it to \c NULL to clear callback for the selected actions.
+ \param iWhich
+ can be one or more (use logical OR) #CallbackType values.
+
+ \see CZipActionCallback
+ \see GetCallback
+
+ */
+ void SetCallback(CZipActionCallback* pCallback = NULL, int iWhich = cbAll);
+
+ /**
+ \return the callback \e iWhich set with #SetCallback
+ */
+ CZipActionCallback* GetCallback(CallbackType iWhich)
+ {
+ return m_callbacks.Get(iWhich);
+ }
+
+ /**
+ Set the callback functor used during operations on a
+ PKZIP compatible disk spanning archive to change disks.
+ Set it before opening the archive. If you open the archive
+ in the \ref PKSpan "PKZIP compatible mode" and don't set the callback functor,
+ the exception CZipException::noCallback will be thrown.
+
+ Callback functor's method CZipSpanCallback::Callback is called when there is a need for a disk change.
+ Calling CZipArchive methods from inside this method may result in an unexpected behavior.
+ \param pCallback
+ the address of the functional object which class is derived from CZipSpanCallback
+ (you need to override member function CZipCallback::Callback in the derived class)
+ Set it to \c NULL to clear the callback.
+
+ \see CZipSpanCallback
+ */
+ void SetSpanCallback(CZipSpanCallback* pCallback = NULL){m_storage.m_pChangeDiskFunc = pCallback;}
+
+
+
+ /**
+ Archive open modes used in #Open(LPCTSTR , int , int )
+ and #Open(CZipMemFile, int )
+ */
+ enum OpenMode
+ {
+ zipOpen, ///< open an existing archive
+ /**
+ Open an existing archive as a read only file.
+ This mode is intended to use in a self extract code or opening
+ archive on storage without write access (e.g. CD-ROMS),
+ If you try to modify the archive in this mode,
+ an exception will be thrown.
+ */
+ zipOpenReadOnly,
+ zipCreate, ///< create a new archive
+ zipCreateSpan ///< create a disk spanning archive
+ };
+
+
+
+/**
+ Open or create a zip archive.
+
+ The archive creation mode depends on \e iMode and \e iVolumesSize values:
+ - if \e iMode == #zipCreateSpan and \e iVolumeSize <= 0 then create disk spanning
+ archive in \ref PKSpan "PKZIP compatible mode" (pkzipSpan)
+ - if \e iMode == #zipCreateSpan and \e iVolumeSize > 0 then create disk spanning
+ archive in \ref TDSpan "TD compatible mode" (tdSpan)
+ - if \e iMode == #zipOpen and the existing archive is a spanned archive
+ then pkzipSpan mode is assumed if the archive is on a removable device
+ or tdSpan otherwise;
+ if you want to open tdSpan archive on a removable device, set \e iVolumeSize
+ to a value different from 0
+ - if \e iMode == #zipCreate then \e iVolumeSize doesn't matter
+
+ \param szPathName
+ the path to the archive
+ \param iMode
+ one of the #OpenMode values
+ \param iVolumeSize
+ the volume size in the disk spanning archive;
+ the size of the volume may be from 1 to INT_MAX ,
+ and the bigger - the faster is creation and extraction (no file changes between volumes) - but the size of the whole archive is the same.
+ If you're creating disk-spanning archive in \ref TDSpan "TD span compatible mode"
+ and plan later to convert it to \ref PKSpan "PKZIP compatible mode" (see \ref sectSpan), it is good to set this this value to
+ about the size of the diskette (a little less just in case).
+
+ \note Throws exceptions.
+ \see Open(CZipMemFile&, int);
+ \see GetSpanMode
+*/
+ void Open(LPCTSTR szPathName, int iMode = zipOpen, int iVolumeSize = 0);
+
+
+/**
+ Open or create the archive in memory. The CZipMemFile object is not closed
+ after closing the archive, so that is it possible to work with it afterwards.
+ \param mf
+ CZipMemFile structure to create archive in or extract from
+ \note This is important: you shouldn't destroy CZipMemFile object before
+ closing the archive, because you'll get an error;
+ \param iMode
+ Open mode.
+ The following modes are valid: #zipOpen, #zipOpenReadOnly, #zipCreate
+ \note Throws exceptions.
+ \see Open(LPCTSTR, int, int);
+*/
+ void Open(CZipMemFile& mf, int iMode = zipOpen);
+
+/**
+ Set #m_szRootPath to a specified value. Use it if you don't want to set
+ \e bFullPath argument in #AddNewFile or #ExtractFile to true and you
+ don't want to strip the whole path neither, but only a specific beginning.
+ Use it AFTER opening the archive and before using #AddNewFile or #ExtractFile.
+ See \ref q9 "the FAQ" for the example of use.
+ \param szPath
+ Set it to the string that you want to be omitted from the beginning of the path of the file
+ in the archive
+ if \c NULL - clears the #m_szRootPath and no path beginning will be matched against it
+
+ \note Set the case-sensitivity with #SetCaseSensitivity
+
+ \see AddNewFile
+ \see ExtractFile
+ \see GetRootPath
+
+*/
+ void SetRootPath(LPCTSTR szPath = NULL);
+
+
+ /**
+ Return the current value of #m_szRootPath
+ \return CZipString
+ */
+ CZipString GetRootPath()const
+ {
+ return m_szRootPath;
+ }
+
+ /**
+ The levels of smartness of the adding files action (see #AddNewFile)
+ \note If you wish to use \e zipsmCheckForEff, you should use
+ \e zipsmNotCompSmall as well, because it will save you the time
+ ( the small file will be surely larger after compression, so that
+ we can add it not compressed straight away);the compression level
+ is always ignored for a directory and set to 0
+ */
+
+ enum Smartness
+ {
+ zipsmLazy = 0x0000, ///< do not bother (you know what you're doing after all)
+ zipsmCPassDir = 0x0001, ///< clear password for directories
+ zipsmCPFile0 = 0x0002, ///< clear password for files of 0 size
+ zipsmNotCompSmall = 0x0004, ///< do not compress files smaller than 5 bytes (they are always stored larger than uncompressed)
+ zipsmCheckForEff = 0x0008, ///< check whether the compressed file is larger than uncompressed and if so, remove it and store without the compression;
+ ///< in the disk spanning mode, the temporary file is used for that: if the file compression is efficient, the data is not compressed
+ ///< again, but moved from the temporary file to the archive; you can use #SetTempPath() to set the path where the
+ ///< file will be created or you can let the library figure it out (the library tries first the system default temporary directory,
+ ///< if it is not present or there is not enough space there, it tries the current directory, if it fails, no temporary file is created
+ ///< and the compression goes the usual way
+
+ zipsmMemoryFlag = 0x0010, ///< combine it with zipsmCheckForEff or use zipsmCheckForEffInMem, you can also use this when replacing files see note at CZipAddNewFileInfo::m_iReplaceIndex
+
+ zipsmCheckForEffInMem = zipsmMemoryFlag | zipsmCheckForEff, ///< the same as #zipsmCheckForEff, but the temporary file is created created in memory instead (the temporary directory set with #SetTempPath() is ignored); has the meaning only with a disk-spanning archive,
+ ///< non-disk spanning archives don't need a temporary file
+ zipsmSmartPass = zipsmCPassDir | zipsmCPFile0, ///< smart password policy (a combination of \e zipsmCPassDir and \e zipsmCPFile0)
+ zipsmSmartAdd = zipsmNotCompSmall | zipsmCheckForEff, ///< smart adding (a combination of \e zipsmNotCompSmall and \e zipsmCheckForEff)
+ zipsmSafeSmart = zipsmSmartPass | zipsmNotCompSmall, ///< safe smart (smartest without checking for efficiency)
+ zipsmSmartest = zipsmSmartPass | zipsmSmartAdd, ///< smart at its best
+
+
+ zipsmInternal01 = 0xf000 ///< for internal use only
+
+ };
+
+
+ /**
+ Add a new file to the archive. You can set the callback functor with #SetCallback.
+ \param info see CZipAddNewFileInfo
+ \return \c if it returns false then the file was not added, but the internal
+ state allows you to add other files (which is not possible after throwing
+ an exception)
+
+ \note
+ - If you abort while adding a file in a non-disk-spanning archive, the added data will be removed from the archive
+ - Throws exceptions.
+
+ \see SetCallback
+ \see AddNewFile(LPCTSTR, LPCTSTR, int, int, unsigned long)
+ \see AddNewFile(LPCTSTR, int, bool, int, unsigned long)
+ \see AddNewFile(CZipMemFile&, LPCTSTR, int, int, unsigned long)
+ */
+ bool AddNewFile(CZipAddNewFileInfo& info);
+ bool AddNewFileDrv(CZipAddNewFileInfo& info);
+
+
+ /**
+ \see AddNewFile(CZipAddNewFileInfo& ); the parameters are equivalent to CZipAddNewFileInfo member variables
+
+ */
+ bool AddNewFile(LPCTSTR lpszFilePath, int iComprLevel = -1, bool bFullPath = true,
+ int iSmartLevel = zipsmSafeSmart, unsigned long nBufSize = 65536);
+
+ bool AddNewFileDrv(LPCTSTR lpszFilePath, int iComprLevel = -1, bool bFullPath = true,
+ int iSmartLevel = zipsmSafeSmart, unsigned long nBufSize = 65536);
+ /**
+ \see AddNewFile(CZipAddNewFileInfo& ); the parameters are equivalent to CZipAddNewFileInfo member variables
+ */
+ bool AddNewFile(LPCTSTR lpszFilePath,
+ LPCTSTR lpszFileNameInZip,
+ int iComprLevel = -1,
+ int iSmartLevel = zipsmSafeSmart,
+ unsigned long nBufSize = 65536);
+
+ /**
+ \see AddNewFile(CZipAddNewFileInfo& ); the parameters are equivalent to CZipAddNewFileInfo member variables
+ */
+ bool AddNewFile(CZipMemFile& mf,
+ LPCTSTR lpszFileNameInZip,
+ int iComprLevel = -1,
+ int iSmartLevel = zipsmSafeSmart,
+ unsigned long nBufSize = 65536);
+
+
+
+/**
+ Add a new file to the opened zip archive. The zip archive cannot be
+ an existing disk spanning archive (existing at the moment of opening archive),
+ because modifying such an archive is not possible (at least not with this
+ version ).
+
+ \param header
+ The structure that provides additional information about the added file.
+ The following fields are valid:
+ - \e m_uMethod - file compression method; can be 0 (storing) or Z_DEFLATE (deflating)
+ otherwise Z_DEFLATE is assumed
+ - \e m_uModDate, \e m_uModTime - Use CZipFileHeader::SetTime to set them.
+ If \e lpszFilePath is not NULL this fields are overwritten and updated automatically.
+ See CZipFileHeader::SetTime
+ - \e m_uExternalAttr - Attributes of the file.
+ If \e lpszFilePath is not NULL this field is overwritten and updated automatically.
+ Use #SetFileHeaderAttr to set them. See #SetFileHeaderAttr.
+ - \e m_szFileName - A filename (may be with path) to be stored inside archive
+ to represent this file. See CZipFileHeader::SetFileName
+ - \e m_szComment - A file comment. See CZipFileHeader::SetComment
+ - \e m_pExtraField - LOCAL extra field, use #SetExtraField after opening
+ a new file, but before closing it to set the not local extra field
+ in the header in the central directory. See #SetExtraField
+ Other fields are ignored - they are updated automatically.
+ If the function returns \c true, \link #GetSystemCompatibility
+ system compatibility \endlink for this object is
+ set to the correct value (the same as #m_iArchiveSystCompatib),
+ additionally if \e lpszFilePath was not NULL, the attributes and
+ the time fields are filled with information retrieved from
+ the file pointed by \e lpszFilePath.
+ \param iLevel
+ The level of compression (-1, 0 - 9).
+ The are several preset values for the compression level:
+ - Z_DEFAULT_COMPRESSION : -1 (equals 6)
+ - Z_NO_COMPRESSION : 0
+ - Z_BEST_SPEED : 1
+ - Z_BEST_COMPRESSION : 9
+ \param lpszFilePath
+ The path to the file to retrieve date stamp and attributes from.
+ These values are stored inside the archive.
+ \param uInternal
+ for internal use only
+
+ \return \c false in the following cases:
+ - the \e lpszFilePath is not NULL and the file attributes and data was not correctly retrieved
+ - a file is already opened for extraction or compression
+ - archive is an existing disk span archive
+ - maximum file count inside archive already reached (65536)
+ \note Throws exceptions.
+
+*/
+ bool OpenNewFile(CZipFileHeader & header, int iLevel = Z_DEFAULT_COMPRESSION, LPCTSTR lpszFilePath = NULL, DWORD uInternal = 0);
+
+/**
+ Compress the contents of the buffer and write it to a new file.
+ \param pBuf
+ the buffer containing the data to be compressed and written
+ \param iSize
+ the number of bytes to be written from the buffer
+ \return \c false if the new file hasn't been opened yet
+ \note Throws exceptions.
+ \see OpenNewFile
+*/
+ bool WriteNewFile(const void *pBuf, DWORD iSize);
+
+
+/**
+ Set the extra field in the central directory of the currently opened file.
+ Must be used after opening a new file in the archive, but before closing it
+ To set the local extra field, set it in the CZipFileHeader structure passed
+ as the argument to the #OpenNewFile
+ \param pBuf
+ the bufer with the data to be copied
+ \param iSize
+ the size of the extra field in the buffer
+ \see OpenNewFile
+*/
+ void SetExtraField(const char *pBuf, WORD iSize);
+
+/**
+ Close the new file in the archive.
+ \return \c false if there is no new file opened
+ \param bAfterException
+ it will close the new file without writing anything (call it also
+ with this parameter set to \c true after an exception other than CZipException::abortedSafely was
+ thrown from one of #AddNewFile functions)
+ \note Throws exceptions.
+ \see OpenNewFile
+*/
+ bool CloseNewFile(bool bAfterException = false);
+
+/**
+ Acquire a file with the given index from another archive.
+ The compressed data of the file from another archive are copied
+ without decompressing to the current archive.
+ You can set the callback functor with #SetCallback.
+ \param zip
+ an opened archive to get the file from (must not be multi-disk)
+ \param uIndex
+ a zero-based index of the file to get from the \e zip archive
+ \param iReplaceIndex the same as CZipAddNewFileInfo::m_iReplaceIndex
+ \param bKeepSystComp
+ if \c false, which is default, then the file from \e zip archive
+ system compatibility is converted to the current archive system
+ compatibility (if they differ)
+ \return \c false if the operation could not be performed (either of archives is closed,
+ a file inside either of archives is opened, \e zip archive is multi-disk or the current
+ archive is an existing multi-disk archive)
+ \note Throws exceptions
+ (when an exception is thrown, you may need to call #CloseNewFile with \e bAfterException set to \c true, to make the archive reusable).
+ \note it is safe to abort the action (by returning false from the callback call) in non-disk spanning archive and when no replacing is taking place
+ (the file not entirely added is removed from the archive)
+ \see SetCallback
+ \see GetFromArchive(CZipArchive& , CZipWordArray &, bool)
+ \see GetFromArchive(CZipArchive& , CZipStringArray &, bool)
+ \see FindMatches
+ \see SetAdvanced
+*/
+ bool GetFromArchive(CZipArchive& zip, WORD uIndex, int iReplaceIndex = -1, bool bKeepSystComp = false)
+ {
+
+ m_info.Init();
+ bool bRet;
+ try
+ {
+ bRet = GetFromArchive(zip, uIndex, iReplaceIndex, bKeepSystComp, GetCallback(cbGetFromArchive));
+ }
+ catch(...)
+ {
+ m_info.ReleaseBuf();
+ throw;
+ }
+ m_info.ReleaseBuf();
+ if (bRet && m_bAutoFlush)
+ Flush();
+
+ return bRet;
+ }
+
+ /**
+ Acquire files with the given indexes from another archive.
+
+ \param aIndexes
+ an array of zero-based indexes of the files inside the \e zip archive
+
+ \see GetFromArchive(CZipArchive& , WORD, int, bool)
+
+ \note
+ - To get files which filenames match a specified pattern, use #FindMatches function
+ */
+ bool GetFromArchive(CZipArchive& zip, CZipWordArray &aIndexes, bool bKeepSystComp = false);
+
+ /**
+ Acquire files with the given indexes from another archive.
+ \param aNames
+ an array of filenames inside the \e zip archive;
+
+ \see GetFromArchive(CZipArchive& , WORD, int, bool)
+ \see EnableFindFast
+
+ \note
+ - Set the case-sensitivity with #SetCaseSensitivity
+ - Enables FindFast if not enabled
+
+ */
+
+ bool GetFromArchive(CZipArchive& zip, CZipStringArray &aNames, bool bKeepSystComp = false)
+ {
+ CZipWordArray indexes;
+ zip.GetIndexes(aNames, indexes);
+ return GetFromArchive(zip, indexes, bKeepSystComp);
+
+ }
+
+ /**
+ Get indexes of the files stored int \e aNames array and put them into \e aIndexes
+ \param aNames
+ an array of filenames inside the archive;
+ \param aIndexes
+ an array of indexes to be build
+ \note
+ - Set the case-sensitivity with #SetCaseSensitivity
+ - Enables FindFast if not enabled
+
+ */
+ void GetIndexes(const CZipStringArray &aNames, CZipWordArray& aIndexes);
+
+/**
+ Extract the file from the archive. You can set the callback functor with #SetCallback.
+ The argument \e lpszNewName may point to the full path and is influenced by \e bFullPath
+ argument (if \e lpszNewName contains drive specification then it is removed)
+ \param uIndex
+ the index of the file to extract
+ \param lpszPath
+ \verbatim
+ The PATH only to extract the file to. May not be NULL. If you wish to
+ use UNC path you need to replace \\\\ at the beginning of UNC path with \\\\?\UNC\ .
+ \endverbatim
+ \param bFullPath
+ - if \c true, then extract with the full path - in this case the resulting
+ file path is \e lpszPath plus the path stored in the archive or plus \e lpszNewName
+ if \e lpszNewName is not NULL.
+ - if \c false, the destination file path is \e lpszPath + \e the filename only
+ extracted from the path stored in the archive or from \e lpszNewName if
+ \e lpszNewName is specified;
+ if #m_szRootPath is set previously with #SetRootPath then to \e lpszPath
+ is added the path stored in the archive (or \e lpszNewName if
+ \e lpszNewName is specified) that has removed the beginning that equals
+ #m_szRootPath (if there is no common beginning then is behaves like
+ #m_szRootPath was empty)
+ \param lpszNewName
+ The new name of the file after extraction.
+ If NULL the original filename stored in the archive is used.
+ May point to the full path but, if \e bFullPath is \c false, only the filename is extracted from this argument,
+ \param nBufSize
+ the size of the buffer used while file operations
+ \return \c true if successful
+ \note
+ - To extract files which filenames match a specified pattern, use #FindMatches function
+ - Throws exceptions.
+ \see SetCallback
+ \see ExtractFile(WORD, CZipMemFile&, DWORD)
+ \see FindMatches
+*/
+ bool ExtractFile(WORD uIndex, LPCTSTR lpszPath, bool bFullPath = true,
+ LPCTSTR lpszNewName = NULL, DWORD nBufSize = 65536);
+
+
+ /**
+ The same as #ExtractFile(WORD , LPCTSTR , bool , LPCTSTR , DWORD )
+ but instead to a physical file, this function decompress the data into CZipMemFile object
+ \note
+ - if you pass CZipMemFile object already with data, its contents are NOT overwirtten, but the decompressed data is appended at the end
+ - if you try to extract a directory, the function will return \c false
+ */
+ bool ExtractFile(WORD uIndex, CZipMemFile& mf, DWORD nBufSize = 65536);
+
+/**
+ Open the file with the given index in the archive for extracting.
+ Not successful opening the file doesn't lock the whole archive, so
+ you can try to open another one (after catching an exception if it was
+ thrown). Throw exception CZipException::badPassword if the password
+ was not set for the encrypted file.
+ \param uIndex
+ the index of the file
+ \return \c true if successful
+ \note Throws exceptions.
+*/
+ bool OpenFile(WORD uIndex);
+
+/**
+ Decompress currently opened file to the buffer.
+ \param pBuf
+ buffer to receive data
+ \param iSize
+ the size of the buffer
+ \return the number of bytes read
+ \see OpenFile
+ \note Throws exceptions.
+*/
+ DWORD ReadFile(void *pBuf, DWORD iSize);
+
+
+/**
+ Test the file with the given index for the integrity. You can set the callback functor with #SetCallback.
+ The method throws exceptions but performs all the necessary cleanup
+ before, so that the next file can be tested after catching the exception.
+ \param uIndex
+ index of the file to test
+ \param uBufSize
+ the size of the buffer used during extraction
+ \return \c false if the incorrect action has been taken by
+ the user or the programmer (it is when #OpenFile or #GetFileInfo returned \c false or \e uBufSize is 0).
+ If the file didn't passed the test or there was a disk I/O error or the password supplied was incorrect, an exception is thrown.
+ \note Throws exceptions.
+ \see SetCallback
+
+*/
+ bool TestFile(WORD uIndex, DWORD uBufSize = 65536);
+
+/**
+ Perform the necessary cleanup after an exception was thrown
+ while testing the archive so that next files in the archive can be tested.
+ Called by #TestFile. Does not remove the file headers
+ information from the central directory.
+ \see TestFile
+ \see CZipCentralDir::Clear
+*/
+ void CloseFileAfterTestFailed();
+
+/**
+ Get the local extra filed of the currently opened
+ for extraction file in the archive.
+ \param pBuf
+ the buffer to receive the data
+ \param iSize
+ the size of the buffer
+ \return If \e pBuf is NULL or iSize is 0, returns the size of the local extra field.
+ Returns -1 if there is no file opened for the extraction.
+*/
+ int GetLocalExtraField(char* pBuf, int iSize)const ;
+
+/**
+ The same as CZipArchive::CloseFile(LPCTSTR), but additionally
+ closes \e file.
+ \param file
+ OPENED CZipFile structure of the extracted file
+ \return
+ \note Throws exceptions.
+ \see CZipArchive::CloseFile(LPCTSTR)
+*/
+ int CloseFile(CZipFile &file);
+
+
+/**
+ Close the file opened for extraction in the archive and copy its date and
+ attributes to the file pointed by \e lpszFilePath
+ \param lpszFilePath
+ Points to the path of the file to have the date and attributes information updated.
+ \param bAfterException
+ Set to \c true to close the file inside archive after an exception has been
+ thrown, to allow futher operations on the archive.
+ \warning Close the file pointed by \e lpszFilePath before using this method,
+ because the system may not be able to retrieve information from it.
+ \return
+ - "1" = ok
+ - "-1" = some bytes left to uncompress - probably due to a bad password or corrupted archive
+ - "-2" = setting extracted file date and attributes was not successful
+ \note Throws exceptions.
+*/
+ int CloseFile(LPCTSTR lpszFilePath = NULL, bool bAfterException = false);
+
+/**
+ Delete the file from the archive with the given index.
+ You can set the callback functor with #SetCallback.
+ If you plan to delete more than one file, use one of DeleteFiles functions rather than calling DeleteFile
+ successively, because these functions are optimized for deleting multiple files
+ \param uIndex
+ a zero-based index
+ \note Throws exceptions.
+ \see SetCallback
+ \see DeleteFiles(CZipWordArray&)
+ \see DeleteFiles(const CZipStringArray&)
+ \see FindMatches
+*/
+ void DeleteFile(WORD uIndex);
+
+/**
+ Delete files from the archive.
+ You can set the callback functor with #SetCallback.
+ Sorts \e aIndexes array in an ascending order.
+ \param aIndexes
+ an array of zero-based indexes of the files inside the archive
+ \note
+ - To remove files which filenames match a specified pattern, use #FindMatches function
+ - Throws exceptions.
+ \see SetCallback
+ \see DeleteFile
+ \see DeleteFiles(const CZipStringArray& )
+ \see FindMatches
+*/
+ void DeleteFiles(CZipWordArray &aIndexes);
+
+
+/**
+ Delete files from the archive.
+ You can set the callback functor with #SetCallback.
+ \param aNames
+ an array of filenames inside the archive;
+ \note
+ - Set the case-sensitivity with #SetCaseSensitivity
+ - Enables FindFast if not enabled
+ - Throws exceptions.
+ \see SetCallback
+ \see DeleteFile
+ \see DeleteFiles(CZipWordArray&)
+ \see EnableFindFast
+*/
+ void DeleteFiles(const CZipStringArray &aNames);
+
+
+/**
+ Set the global comment in the archive.
+ \param lpszComment
+ the file comment
+ \return \c false if the archive is closed or if it is an existing disk spanning archive
+ \note Throws exceptions.
+*/
+ bool SetGlobalComment(LPCTSTR lpszComment);
+
+
+/**
+ \return the global comment or an empty string if the archive is closed
+*/
+ CZipString GetGlobalComment()const ;
+
+
+/**
+ Set the comment of the file with the given index inside the archive.
+ \param uIndex
+ zero-based index of the file in the archive
+ \param lpszComment
+ a comment to add
+ \return \c false if the comment change is impossible
+ \note Throws exceptions.
+*/
+ bool SetFileComment(WORD uIndex, LPCTSTR lpszComment);
+
+/**
+ \return the path of the currently opened archive volume
+*/
+ CZipString GetArchivePath()const;
+
+/**
+ \return
+ - a one-based number of the current disk
+ - 0 if there is no current disk (the archive is closed)
+ \note Useful mostly while working with the disk-spanning archive in creation to find out
+ how many disks were already created. To find out how many disks are in an existing disk-spanning archive,
+ use the function #GetCentralDirInfo
+*/
+ int GetCurrentDisk()const ;
+
+/**
+ Return the disk spanning mode of the current archive.
+
+ \return
+ - -2 - existing TD mode compatible disk spanning archive
+ - -1 - existing PKZIP compatible
+ - 0 - no disk spanning
+ - 1 - PKZIP compatible in creation
+ - 2 - TD compatible in creation
+
+ \see \ref PKSpan, \ref TDSpan
+
+*/
+ int GetSpanMode()const
+ {
+ return m_storage.m_iSpanMode * m_storage.IsSpanMode();
+ }
+
+ /**
+ case-sensitivity values used as argument \e iCaseSensitive in #FindFile
+ */
+ enum FFCaseSens
+ {
+ ffDefault, ///< use the default case-sensitivity as set with #SetCaseSensitivity function;
+ ///< if CZipCentralDir::m_findarray was build before with a different case-sensitivity,
+ ///< it is rebuild again, if it hasn't been build so far, it is build now with the
+ ///< default case-sensitivity
+ ffCaseSens, ///< perform a case-sensitive search (if the \c CZipArchive is non-case-sensitive,
+ ///< a less effective search is perfomed); does not rebuild CZipCentralDir::m_findarray,
+ ///< but if the array hasn't been built yet, it is build now as \b non-case-sensitive
+ ///< (you can use \c SetCaseSensitivity(true) and then #ffDefault to build it as case-sensitive)
+ ffNoCaseSens ///< perform a non-case-sensitive search (if the \c CZipArchive is case-sensitive,
+ ///< a less effective search is performed); does not rebuild CZipCentralDir::m_findarray,
+ ///< but if the array hasn't been built yet, it is build now as \b case-sensitive
+ ///< (you can use \c SetCaseSensitivity(false) and then #ffDefault to build it as non-case-sensitive)
+
+ };
+
+/**
+ Find the file in the archive.
+ If the archive wasn't opened with CZipCentralDir::m_bConvertAfterOpen set to \c true,
+ this function automatically convert all the filenames with the function
+ CZipCentralDir::ConvertAll and set CZipCentralDir::m_bConvertAfterOpen to \c true.
+ This function requires \link CZipCentralDir::m_bFindFastEnabled FindFast \endlink
+ feature enabled.
+ \param lpszFileName
+ the name of the file to be found in the archive; must be with path unless
+ you set \e bFileNameOnly to \c true. Use path separators the same as they are for your system
+ (\e "\" for Windows and \e "/" for Unix/Linux)
+ \param iCaseSensitive can be one of #FFCaseSens values
+ \param bFileNameOnly
+ if \c true, the function tries to find a filename without a path (a less effective search is performed); if you wish to find
+ a directory name, do not end it with the path separator, which is required if you set \e bFileName to \c false
+ \return
+ - the index of the file found
+ - -1 if there is no such a file in the archive
+ \see CZipCentralDir::FindFileNameIndex
+ \see EnableFindFast
+ \see CZipCentralDir::ConvertAll
+ \see SetConvertAfterOpen
+*/
+ int FindFile(LPCTSTR lpszFileName, int iCaseSensitive = ffDefault, bool bFileNameOnly = false);
+
+/**
+ Get the info of the file with the given index.
+ \param fhInfo
+ the structure to receive info
+ \param uIndex
+ a zero-based index of the file inside the archive
+ \return \c true if successful
+*/
+ bool GetFileInfo(CZipFileHeader & fhInfo, WORD uIndex) const;
+
+
+/**
+ \param bOnlyFiles
+ if \c true, the directories are not inluded in a total count;
+ default is \c false
+ \return the number of files in the archive
+*/
+ int GetCount(bool bOnlyFiles = false)const
+ {
+ int iTotalCount = m_centralDir.m_headers.GetSize();
+ if (bOnlyFiles)
+ {
+ int iCount = 0;
+ for (int i = 0; i < iTotalCount; i++)
+ if (!m_centralDir.m_headers[i]->IsDirectory())
+ iCount++;
+ return iCount;
+ }
+ else
+ return iTotalCount;
+ }
+
+ /**
+ values used in #Close function as parameter \e iAfterException
+ */
+ enum CloseAfterException
+ {
+ afNoException, ///< normal close, no exception was thrown before by CZipArchive object
+ afAfterException, ///< an exception has been thrown, don't write any data but perform necessary cleaning to reuse CZipArchive object for another archive
+ afWriteDir ///< the same as above, but write the central directory end structure to the archive, so that we can save at least the files that have
+ ///< been added properly and maybe try to repair the archive later
+ };
+
+/**
+ Close the archive.
+ \param iAfterException
+ one of #CloseAfterException enum values
+ \param bUpdateTimeStamp
+ if \c true, set the modification date of the zip file to the date of the newest file in the archive;
+ in disk-spanning mode only the last archive file will have the time stamp updated;
+ you can use this option even without performing any additional processing on the archive, just open and close it
+ \note Throws exceptions if \e iAfterException is different from \c afAfterException
+*/
+ void Close(int iAfterException = afNoException, bool bUpdateTimeStamp = false);
+
+
+/**
+ Test if the archive is closed (a whole or the current volume only)
+ \param bArchive
+ - \c true: test for the whole archive
+ - \c false: test for the volume file only
+
+ \return \c true if closed
+*/
+ bool IsClosed(bool bArchive = true)const ;
+
+ /**
+ Write the central directory to the archive and flushes the internal buffers to the disk,
+ so that the archive is finalized on the disk, but you can still modify it. Use it after
+ opening (or creating) and modifying the archive if you want to prevent the loss
+ of the data you've compressed so far in case of the program crash.
+ If you use it on a disk spanning archive in creation it will not be closed, but its state
+ will be changed from "archive in creation" to "an existing span archive". Use it when you finish adding files to the disk-spanning archive and want to
+ begin extracting or testing it. It follows that you can call it only once in this case. However, if
+ after finalizing the disk spanning archive it turns out that it is one disk only, it is converted to
+ a normal archive and you can use it as such. If you want to know what is the state of the archive after using
+ this function call #GetSpanMode.
+ \note
+ - Cannot be used on existing disk spanning archives (they are not modifable anyway)
+ - If you have an archive with a huge central directory, it'll influence the perfomance calling this function without a reason.
+ - Throws exceptions.
+ \see GetSpanMode
+ \see SetAutoFlush
+ \see GetAutoFlush
+
+ */
+ void Flush();
+
+
+ /**
+ Set the CZipArchive object to call #Flush after each operation that modifies the archive
+ (adding a new file, deleting file(s), modifying the global or a file comment).
+ It is useful when we want to prevent the loss of data in case of the program crash - the zip file will be then finalized on the disk.
+ Use it after opening the archive.
+ \note
+ - You can set AutoFlush only for non-disk spanning archives, however you can call #Flush once for a disk-spanning archive in creation.
+ - If you have an archive with a huge central directory, setting Auto-Flush will influence the performance.
+ \see Flush
+ \see GetAutoFlush
+ */
+ void SetAutoFlush(bool bAutoFlush = true);
+
+
+ /**
+ return the current #m_bAutoFlush value
+ \see Flush
+ \see SetAutoFlush
+ */
+ bool GetAutoFlush()const {return m_bAutoFlush;}
+
+/**
+ Return the system compatibility of the current archive.
+ System compatibility value for the single file in the archive
+ (represented by CZipFileHeader) influences file attributes conversion
+ (the file attributes are defined differently across the platforms).
+ When opening an existing archive CZipArchive assumes the system compatibility
+ of the whole archive to be the same as of the first file in the archive
+ (if present). In other cases the current system value is assumed which is
+ taken from ZipPlatform::GetSystemID during creating or opening an archive
+ \remark
+ If the existing archive during opening is empty, ZipPlatform::GetSystemID
+ is assumed to be the default system for the files that will be added to the archive.
+
+ \return
+ one of the enum values defined in \link ZipCompatibility::ZipPlatforms
+ ZipCompatibility.h \endlink
+ \see ZipCompatibility::ZipPlatforms
+ \see ZipPlatform::GetSystemID
+ \see CZipFileHeader::GetSystemCompatibility
+*/
+ int GetSystemCompatibility() const {return m_iArchiveSystCompatib;}
+
+/**
+ Set the system compatibility of the archive. By default it is set to the
+ current system value (the one returned by ZipPlatform::GetSystemID() function).
+ Use it after opening the archive, but before adding a new file or using
+ SetFileHeaderAttr() function
+ \param iSystemComp
+ can be one of ZipCompatibility::ZipPlatforms values
+ \return
+ return \c false if the value \e iSystemComp is not supported
+ (ZipCompatibility::IsPlatformSupported returns \c false for the value)
+ or it is not possible to set it right now
+*/
+ bool SetSystemCompatibility(int iSystemComp);
+
+/**
+ Set the attributes for CZipFileHeader structure to be used
+ in #OpenNewFile method as an argument.
+ This special procedure is taken, because the system compatibility must
+ be set for CZipFileHeader prior to the value, which must be identical to
+ the return value of #GetSystemCompatibility method.
+ \param header
+ the structure to have attributes set
+ \param uAttr
+ attributes to set
+ \note Throws exceptions if the archive system or the current system
+ is not supported by the ZipArchive library.
+ \see GetSystemCompatibility
+*/
+ void SetFileHeaderAttr(CZipFileHeader& header, DWORD uAttr);
+
+
+/**
+ A helper for a various purposes (needed e.g. by the program that
+ cracks the zip archives password)
+ \return the pointer to the static CRC table in the zlib library
+
+*/
+ static const DWORD* GetCRCTable()
+ {
+ return get_crc_table();
+ }
+
+/**
+ Return the underlying archive storage medium.
+ \warning A method for a very advanced use - you normally never need it.
+ \return the pointer to #m_storage
+ \see CZipStorage
+*/
+ CZipStorage* GetStorage(){return &m_storage;}
+
+
+/**
+ Set #m_bDetectZlibMemoryLeaks value.
+ \param bDetect
+ \note Use before opening a file in the archive.
+ \see m_bDetectZlibMemoryLeaks
+
+*/
+/*
+ void SetDetectZlibMemoryLeaks(bool bDetect)
+ {
+ if (m_iFileOpened != nothing)
+ {
+ TRACE(_T("CZipArchive::SetDetectZlibMemoryLeaks: Set it before opening a file in the archive"));
+ return;
+ }
+ m_bDetectZlibMemoryLeaks = bDetect;
+
+ }
+*/
+/**
+ Set CZipCentralDir::m_bConvertAfterOpen value.
+ The default value is \c true.
+ Setting this value to \c false is generally not effective and is intended
+ only for quick and short operations on archives with lots of files inside
+ (e.g. open archive, make an operation on a file which index you already know
+ and close the archive - using #FindFile function already makes setting this
+ value to \c false inefficient)
+
+ \param bConvertAfterOpen
+ \note Use before opening the archive.
+ \see CZipCentralDir::m_bConvertAfterOpen
+*/
+ void SetConvertAfterOpen (bool bConvertAfterOpen)
+ {
+ if (!IsClosed())
+ {
+ TRACE(_T("CZipArchive::SetConvertAfterOpen: Set it before opening the archive"));
+ return;
+ }
+ m_centralDir.m_bConvertAfterOpen = bConvertAfterOpen;
+
+ }
+
+/**
+ Enable fast finding by the file name of the files inside the archive.
+ Set CZipCentralDir::m_bFindFastEnabled to \c true, which is required by #FindFile.
+ #FindFileIt is called by #FindFileif necessary. It builds CZipCentralDir::m_findarray
+ with the default case-sensitivity (set with #SetCaseSensitivity)
+ \note Call it only after opening the archive.
+ \param bEnable
+ \see CZipCentralDir::m_bFindFastEnabled
+ \see FindFile
+*/
+ void EnableFindFast(bool bEnable = true);
+
+
+ /**
+ After you enable FindFast feature with #EnableFindFast, you can retrieve
+ how the files are sorted in CZipCentralDir::m_findarray (you can use it
+ in your own program if you need to display the sorted list and do not want
+ to duplicate data)
+
+ \param iFindFastIndex
+ index in CZipCentralDir::m_findarray (not necessary the same as the one you'd
+ pass to #GetFileInfo); the number of items in this array is the same
+ as the number of files in the archive (you can retrieve it with
+ #GetCount)
+
+ \return
+ index of the file in central directory (now you can call #GetFileInfo to get
+ the information); if the value is \c -1 then you have not called
+ #EnableFindFast before or the archive is closed or the \e iFindFastIndex
+ is out of range)
+ */
+ int GetFindFastIndex(int iFindFastIndex) const
+ {
+ if (IsClosed())
+ {
+ TRACE(_T("CZipArchive::GetFindFastIndex: ZipArchive not yet opened.\n"));
+ return -1;
+ }
+
+ return m_centralDir.GetFindFastIndex(iFindFastIndex);
+ }
+
+
+ /**
+ Set a temporary path used when compressing files and #zipsmCheckForEff
+ is specified as an argument in #AddNewFile and the disk spanning archive
+ is in creation.
+ \param lpszPath set it to NULL to clear the temporary path and let the
+ library figure it out (it uses the system temporary directory if possible)
+ \param bForce if \e lpszPath is not \c NULL and this parameter set to \c true
+ the directory is created if it doesn't exists (if the given directory
+ does not exists , the temporary file will not be created)
+ \see AddNewFile
+ \see Smartness
+ \see GetTempPath
+ */
+ void SetTempPath(LPCTSTR lpszPath = NULL, bool bForce = true);
+
+
+
+ /**
+ enum values used in #PredictFileNameInZip
+ */
+ enum Predict
+ {
+
+ prDir, ///< if an argument is a directory, add a separator at the end
+ prFile, ///< treat the argument as a common file
+ prAuto ///< treat the argument as a directory only if it has a path separator at the end
+
+ };
+
+ /**
+ Given the file path in the form it would be passed to #AddNewFile
+ as \e lpszFilePath argument, the function returns the file name
+ as it would be stored in the archive.
+ The function takes into account the root path set with #SetRootPath. You can use this function
+ to eliminate duplicates before adding a list of files.
+
+ \param lpszFilePath
+ the file path as it would be passed to #AddNewFile function
+ \param bFullPath
+ the same as \e bFullPath in #AddNewFile
+ \param iWhat
+ one of #Predict values to treat \e lpszFilePath correctly
+ \param bExactly
+ if \c true, return the filename exactly as it would look inside the archive i.e. convert slash to backslash, and perform ANSI->OEM conversion;
+ otherwise return the filename with the path separators that are used by default in the system
+
+ \return a modified file path
+ */
+ CZipString PredictFileNameInZip(LPCTSTR lpszFilePath, bool bFullPath, int iWhat = prAuto, bool bExactly = false)const ;
+
+ /**
+ Check if the filename will be duplicted in the archive, if added to the archive in the given form
+ \param bFileNameOnly
+ if \c true, assume that the filename is duplicated if only the filename (no path) is the same (\e bFullPath is ignored), otherwise the whole filename with path is taken into account.
+
+ \b Default: \c false
+
+ The rest of the parameters have the same meaning as in #PredictFileNameInZip.
+
+ \return the zero-based index of the file in the archive that the filename would be duplicated, or -1, if the filename is unique
+ */
+ int WillBeDuplicated(LPCTSTR lpszFilePath, bool bFullPath, bool bFileNameOnly = false, int iWhat = prAuto);
+
+
+ /**
+ Predict the full filename with path after extraction. The parameters (except for the first) are in the form you'd pass
+ to the #ExtractFile(WORD , LPCTSTR , bool , LPCTSTR , DWORD ) function. The function takes into account the root path set with #SetRootPath.
+ \param lpszFileNameInZip
+ the filename of the file inside the archive (may be \c NULL if lpszNewName is not \c NULL)
+ \param lpszPath
+ \param bFullPath
+ \param lpszNewName
+ \return a predicted file path
+ */
+ CZipString PredictExtractedFileName(LPCTSTR lpszFileNameInZip, LPCTSTR lpszPath, bool bFullPath, LPCTSTR lpszNewName = NULL)const ;
+
+ /**
+
+ Return the current value of #m_szTempPath
+
+ \return CZipString
+ */
+ CZipString GetTempPath()const
+ {
+ return m_szTempPath;
+ }
+
+/**
+ Function used in conjunction with #m_szRootPath to trim paths in #AddNewFile and #ExtractFile
+ \param zpc
+ \see SetRootPath
+
+*/
+ CZipString TrimRootPath(CZipPathComponent& zpc)const ;
+
+ /**
+ Remove \e lpszBeginning from the beginning of the \e szPath. Both argument are
+ considered to be paths so they matches up to the path separator.
+
+ \param lpszBeginning
+ \param szPath
+ \param pCompareFunction (see: #m_pZipCompare)
+
+
+ \return \c true if the path beginning was removed
+ */
+ static bool RemovePathBeginning(LPCTSTR lpszBeginning, CZipString& szPath, ZIPSTRINGCOMPARE pCompareFunction);
+
+ /**
+ Set the default archive case-sensitivity. Affects the following functions:
+ - #FindFile
+ - #FindMatches
+ - #EnableFindFast
+ - #TrimRootPath
+ - #DeleteFiles
+
+
+
+ \param bCaseSensitive
+ the default CZipArchive case-sensitivity depends on the system and is set
+ as follows:
+ - on Windows: \c false
+ - on Linux: \c true
+ \note Set it before using one of the functions above or leave it as it is by default;
+
+ */
+
+ void SetCaseSensitivity(bool bCaseSensitive)
+ {
+ m_bCaseSensitive = bCaseSensitive;
+ m_pZipCompare = GetCZipStrCompFunc(bCaseSensitive);
+ }
+
+ /**
+ Return the central directory information.
+ \see GetCentralDirSize
+ */
+ void GetCentralDirInfo(CZipCentralDir::Info& info)const;
+
+
+ /**
+ Get the central directory size.
+ \see CZipCentralDir::GetSize
+ \see GetCentralDirInfo
+ */
+ DWORD GetCentralDirSize(bool bWhole = true) const
+ {
+ return m_centralDir.GetSize(bWhole);
+ }
+
+ /**
+ return \c true if the archive cannot be modified, because it is an existing disk spanning archive
+ or it was opened with #zipOpenReadOnly
+ */
+ bool IsReadOnly(){return m_storage.IsReadOnly();}
+
+
+ /**
+
+ If you set \e bIgnore to \c true, CRC is not checked for the files being tested or extracted.
+ This method is useful when working with Java TM Archives (jar).
+ The CRC is checked by default. You can use this function on an opened or closed archive.
+
+ */
+ void SetIgnoreCRC(bool bIgnore = true){m_bIgnoreCRC = bIgnore;}
+
+ /**
+ A class used in wildcard pattern matching.
+ This class is based on code by J. Kercheval, created 01/05/1991
+ and available as a public domain at http://www.snippets.org.
+ */
+ class ZIP_API CWildcard
+ {
+ public:
+
+
+ enum Match
+ {
+ matchNone, ///< for internal use
+ matchValid, ///< valid match
+ matchEnd, ///< premature end of pattern string
+ matchAbort, ///< premature end of text string
+ matchRange, ///< match failure on [..] construct
+ matchLiteral, ///< match failure on literal match
+ matchPattern ///< bad pattern
+ };
+
+ enum Pattern
+ {
+ patternEmpty = -4, ///< [..] construct is empty
+ patternClose, ///< no end bracket in [..] construct
+ patternRange, ///< malformed range in [..] construct
+ patternEsc, ///< literal escape at end of pattern
+ patternValid, ///< valid pattern
+ };
+
+
+ /**
+ Match the pattern against the string \e lpszText
+ A match means the entire string \e lpszText is used up in matching.
+
+ \param lpszText
+ the string to match against
+ \param iRetCode
+ if not \c NULL, set to one of #Match values indicating the return code
+ \return \c true if \e lpszText matches the pattern.
+ \see SetPattern
+ */
+ bool IsMatch(LPCTSTR lpszText, int* iRetCode = NULL);
+
+ /**
+
+ \param lpszPattern
+
+ \return \c true if \e lpszPattern has any special wildcard characters.
+
+ */
+ static bool IsPattern(LPCTSTR lpszPattern);
+
+ /**
+ Test the pattern for validity.
+
+ \param lpszPattern
+ the pattern to test
+ \param iErrorType
+ if not \c NULL, set to one of #Pattern values indicating the return code
+ \return \c true if \e lpszPattern is a well formed regular expression according
+ to the CWildcard class syntax (see #SetPattern)
+ */
+ static bool IsPatternValid(LPCTSTR lpszPattern, int* iErrorType = NULL);
+
+ /**
+ Match the pattern \e lpszPattern against the string \e lpszText
+ A match means the entire string \e lpszText is used up in matching.
+
+
+ \param lpszPattern
+ see #SetPattern
+ \param lpszText
+ the string to match against
+ \return
+ one of #Match values
+ */
+ static int Match(LPCTSTR lpszPattern, LPCTSTR lpszText);
+
+ CWildcard(){}
+ /**
+ Initialize the pattern.
+ \see SetPattern
+ */
+ CWildcard(LPCTSTR lpszPattern, bool bCaseSensitive)
+ {
+ SetPattern(lpszPattern, bCaseSensitive);
+ }
+ virtual ~CWildcard(){}
+
+ /**
+ Set the pattern to \e lpszPattern.
+ \param lpszPattern
+
+ In the pattern string:
+ - * matches any sequence of characters(zero or more)
+ - ? matches any character
+ - [SET] matches any character in the specified set,
+ - [!SET] or[^SET] matches any character not in the specified set.
+
+ A set is composed of characters or ranges; a range looks like
+ character hyphen character(as in 0 - 9 or A - Z).[0 - 9a - zA - Z_] is the
+ minimal set of characters allowed in the[..] pattern construct.
+ Other characters are allowed(ie. 8 bit characters) if your system
+ will support them.
+
+ \note To suppress the special syntactic significance of any of []*?!^-\,
+ and match the character exactly, precede it with a \
+ */
+ void SetPattern(LPCTSTR lpszPattern, bool bCaseSensitive)
+ {
+ m_szPattern = lpszPattern;
+ m_bCaseSensitive=bCaseSensitive;
+ if (!bCaseSensitive)
+ m_szPattern.MakeLower();
+ }
+ operator LPCTSTR()
+ {
+ return (LPCTSTR)m_szPattern;
+ }
+ protected:
+ bool m_bCaseSensitive;
+ static int MatchAfterStar(LPCTSTR p , LPCTSTR t);
+ CZipString m_szPattern;
+ };
+
+
+ /**
+ This function finds the indexes of the files, which filenames match the specified pattern and stores
+ these indexes in the array. The indexes can be used then e.g. in deleting (CZipArchive::DeleteFiles) or
+ extracting files (CZipArchive::ExtractFile).
+
+ \param lpszPattern
+ the pattern to match (see CWildcard::SetPattern on how to build the pattern). The case-sensitivity of the pattern
+ is set to the global archive case-sensitivity (set with #SetCaseSensitivity)
+ \param ar
+ the array which will contain the indexes of the files which filenames match the pattern; the contents of the array are NOT clearead, but the
+ indexes are appended to it
+ \param bFullPath
+ - if \c true, match the filename with path (if present) of the file (if the file is a directory, end it with the path separator or use a pattern that will recognize it)
+ - otherwise match only the name of the file (if the file is a directory, do not end it with the path separator)
+
+ */
+ void FindMatches(LPCTSTR lpszPattern, CZipWordArray& ar, bool bFullPath = true)const;
+
+
+ /**
+ Change the name of the file with the given index.
+
+ \param uIndex
+ zero-based index of the file
+ \param lpszNewName
+ new name for the file
+ \return
+
+ \note Throws exceptions.
+ \see SetAdvanced
+ */
+ bool RenameFile(WORD uIndex, LPCTSTR lpszNewName);
+
+ /**
+
+ If \c true, the drive letter is removed from the filename stored inside the archive when adding a new file to the archive. It affects
+ #AddNewFile, #ExtractFile, #PredictFileNameInZip, #PredictExtractedFileName, #WillBeDuplicated methods.
+
+ \b Default: \c true
+ */
+ bool m_bRemoveDriveLetter;
+
+protected:
+
+ /**
+ \param iReplaceIndex index of file to be replaced
+ \param uTotal the size of the new file to replace existing
+ \param lpszFileName the filename for callback initialization
+ */
+ void MakeSpaceForReplace(int iReplaceIndex, DWORD uTotal, LPCTSTR lpszFileName);
+ /**
+ A structure for the internal use only. Clears the password if necessary and
+ restores it later (also in case of an exception).
+ */
+ struct ZIP_API CZipSmClrPass
+ {
+ void ClearPasswordSmartly(CZipArchive* pZip)
+ {
+ m_pZip = pZip;
+ m_szPass = pZip->GetPassword();
+ if (!m_szPass.IsEmpty())
+ pZip->SetPassword();
+ }
+ ~CZipSmClrPass()
+ {
+ if (!m_szPass.IsEmpty())
+ m_pZip->SetPassword(m_szPass);
+ }
+ CZipString m_szPass;
+ CZipArchive* m_pZip;
+ };
+
+ /**
+ Holds map of holes and areas to remain when deleting files from the archive.
+ A structure for the internal use only.
+ */
+ struct ZIP_API CZipDeleteInfo
+ {
+ CZipDeleteInfo(){m_pHeader = NULL; m_bDelete = false;}
+ CZipDeleteInfo(CZipFileHeader* pHeader, bool bDelete)
+ :m_pHeader(pHeader), m_bDelete (bDelete){}
+ CZipFileHeader* m_pHeader;
+ bool m_bDelete;
+ };
+
+
+ /**
+ Storage for callback functors. A structure for the internal use only.
+ \see SetCallback
+ */
+ struct ZIP_API CZipClbckStrg : public CZipMap
+ {
+ void Set(CZipActionCallback* pCallback, CallbackType iType)
+ {
+ if (pCallback)
+ {
+ SetAt(iType, pCallback);
+ }
+ else
+ RemoveKey(iType);
+ }
+ CZipActionCallback* Get(CallbackType iType)
+ {
+ CZipActionCallback* pCallback = NULL;
+ if (Lookup(iType, pCallback))
+ {
+ pCallback->m_iType = iType;
+ return pCallback;
+ }
+ else
+ return NULL;
+ }
+
+ };
+
+
+ /**
+ \see CZipClbckStrg
+ */
+ CZipClbckStrg m_callbacks;
+
+
+ /**
+ Write central directory calling a callback functor if available
+ */
+ void WriteCentralDirectory(bool bFlush = true);
+
+ /**
+ Default archive case-sensitivity
+ \see SetCaseSensitivity
+ */
+ bool m_bCaseSensitive;
+
+ /**
+ a pointer to the function in CZipString structure,
+ used to compare elements; can point to Compare, CompareNoCase,
+ Collate or CollateNoCase function address in CZipString structure ZIPSTRINGCOMPARE is defined as follows:
+ typedef int (CZipString::*ZIPSTRINGCOMPARE)( LPCTSTR ) const;
+ */
+ ZIPSTRINGCOMPARE m_pZipCompare;
+
+ /**
+ Internal data.
+ \see CZipInternalInfo
+ */
+ CZipInternalInfo m_info;
+
+
+ /**
+ Physical layer of the archive.
+ \see CZipStorage
+ */
+ CZipStorage m_storage;
+
+ /**
+ A central directory object.
+ \see CZipCentralDir
+ */
+ CZipCentralDir m_centralDir;
+
+ /**
+ The open mode of the current file inside archive.
+ */
+ enum OpenFileType
+ {
+ extract = -1, ///< current file opened for extraction
+ nothing, ///< no file inside archive opened
+ compress ///< a new file opened for compression
+ };
+
+ /**
+ Takes one of the #OpenFileType enum values.
+ */
+ char m_iFileOpened;
+
+ /**
+ The current AutoFlush value.
+ \see Flush
+ \see SetAutoFlush
+ \see GetAutoFlush
+ */
+ bool m_bAutoFlush;
+
+ /**
+ The value set with #SetIgnoreCRC
+ */
+ bool m_bIgnoreCRC;
+
+
+
+/**
+ The root path to be omitted in #AddNewFile and #ExtractFile functions
+ from the beginning of the full file path. Set by #SetRootPath
+ \see TrimRootPath
+ \see SetRootPath
+*/
+ CZipString m_szRootPath;
+
+ /**
+ A temporary path set with #SetTempPath function
+ \see SetTempPath
+ \see AddNewFile
+ \see Smartness
+ */
+ CZipString m_szTempPath;
+
+/**
+ Open the archive in the given mode.
+ Called by #Open(LPCTSTR, int, int) and #Open(CZipMemFile&, int).
+ \param iMode
+ an opening mode
+ \note Throws exceptions.
+*/
+ void OpenInternal(int iMode);
+
+ /**
+ The system code of the current archive. All new files in the archive
+ will be created regarding this value. Can be one of the enum values
+ defined in \link ZipCompatibility::ZipPlatforms ZipCompatibility.h
+ \endlink
+
+ \see GetSystemCompatibility
+ */
+ int m_iArchiveSystCompatib;
+
+/**
+ Free the memory allocated by the zlib library that hasn't been freed
+ due to an error in the zlib library (usually never happens).
+*/
+ void EmptyPtrList();
+
+
+
+/**
+ Move the range of data in the archive specified by the \e uStartOffset
+ and \e uEndOffset by \e uToMove
+
+*/
+ void MovePackedFiles(DWORD uStartOffset, DWORD uEndOffset, DWORD uMoveBy, CZipActionCallback* pCallback, bool bForward = false);
+
+ /**
+ Remove recently added file (used by AddNewFile) if compressed is larger than uncompressed or if callback method return \c false.
+ \param bRemoveAnyway if \c true, do not check for the efficiency, but remove the file
+
+ */
+ bool RemoveLast(bool bRemoveAnyway = false);
+
+ /**
+ It is used in GetFromArchive public functions and in AddNewFile and the callback parameter is needed
+ */
+ bool GetFromArchive(CZipArchive& zip, WORD uIndex, int iReplaceIndex, bool bKeepSystComp, CZipActionCallback* pCallback);
+
+ /**
+ \return whether the code should continue or not
+ */
+ bool UpdateReplaceIndex(int& iReplaceIndex, LPCTSTR lpszNewFileName);
+
+/**
+ \return the currently opened for compression or decompression
+ file inside the archive NULL if there is no file opened
+*/
+ CZipFileHeader* CurrentFile();
+
+/**
+ If the parameter \e iErr signalizes a zlib library error, throw CZipException
+ \param iErr
+ a zlib library error to check
+ \note Throws exceptions.
+*/
+ void CheckForError(int iErr);
+
+
+/**
+ Throw a CZipException error.
+ \param err
+ the error code
+ \see CZipException::ZipErrors
+ \param bZlib
+ if \c true, treat \e err as a zlib error code and perform the conversion to the one of CZipException codes.
+ \see CZipException::Throw
+*/
+ void ThrowError(int err, bool bZlib = false);
+
+
+ typedef CZipPtrList::iterator CZipPtrListIter;
+ CZipPtrList m_list; ///< a list holding pointers to the memory areas allocated by the zlib library
+
+
+ static void* _zliballoc(void* opaque, UINT items, UINT size); ///< memory allocator called by the zlib library
+ static void _zlibfree(void* opaque, void* address); ///< memory deallocator called by the zlib library
+
+
+ /**
+ Specify whether to control memory allocation and freeing by the zlib library.
+
+ \b Default: \c true
+ \note Set it before opening a file (new or existing) in the archive.
+ \see SetDetectZlibMemoryLeaks
+
+ */
+// bool m_bDetectZlibMemoryLeaks;
+
+
+ /**
+ Copyright string.
+ */
+ static const TCHAR m_gszCopyright[];
+
+/**
+ \defgroup Cryptography Cryptography
+ Methods performing data encryption and decryption
+ and attributes used by them.
+*/
+ /*@{*/
+
+/**
+ Decode \e uCount bytes from the internal buffer.
+ \see m_info
+ \see CZipInternalInfo::m_pBuffer
+
+*/
+ void CryptDecodeBuffer(DWORD uCount);
+/**
+ Encode the internal buffer.
+ \see m_info
+ \see CZipInternalInfo::m_pBuffer
+*/
+ void CryptEncodeBuffer();
+
+/**
+ Encode the character \e c and update \link #m_keys encryption keys \endlink.
+
+*/
+ void CryptEncode(char &c);
+/**
+ Create an encryption header for the new file in the archive.
+ \param iCrc
+ A control value. Use the two lower bytes of CZipFileHeader::m_uModTime.
+ This entails the need for a data description presence at the end of
+ the compressed data. We cannot use the real CRC now, because we don't know
+ it yet.
+ \param buf
+ a buffer to receive the header
+ \see CryptCheck
+*/
+ void CryptCryptHeader(long iCrc, CZipAutoBuffer& buf);
+/**
+ \internal
+ \return
+*/
+ DWORD CryptCRC32(DWORD l, char c);
+/**
+ Decode the character \e c and update \link #m_keys encryption keys \endlink.
+*/
+ void CryptDecode(char &c);
+ /**
+ \internal
+ */
+ char CryptDecryptByte();
+
+/**
+ Decrypt the encryption header and check its control value.
+ The control value depends on the presence of the data descriptor.
+ \return \c true if the control value is correct
+ \see CryptCryptHeader
+*/
+ bool CryptCheck();
+/**
+ Update \link #m_keys encryption keys \endlink with the given value.
+*/
+ void CryptUpdateKeys(char c);
+/**
+ Initialize \link #m_keys encryption keys \endlink.
+*/
+ void CryptInitKeys();
+ /**
+ The archive password. If empty, the new file will not be encrypted.
+ */
+ CZipAutoBuffer m_pszPassword;
+
+ /**
+ Encryption keys.
+ The key values are initialized using a supplied encryption password.
+ \see CryptInitKeys
+ */
+ DWORD m_keys[3];
+
+ /*@}*/
+};
+
+
+
+#endif // !defined(AFX_ZIPARCHIVE_H__A7F528A6_1872_4071_BE66_D56CC2DDE0E6__INCLUDED_)
diff --git a/harbour/contrib/hbzlib/zipautobuffer.h b/harbour/contrib/hbzlib/include/zipautobuffer.h
similarity index 71%
rename from harbour/contrib/hbzlib/zipautobuffer.h
rename to harbour/contrib/hbzlib/include/zipautobuffer.h
index 0dbd4093e6..533f7c1328 100644
--- a/harbour/contrib/hbzlib/zipautobuffer.h
+++ b/harbour/contrib/hbzlib/include/zipautobuffer.h
@@ -1,12 +1,11 @@
-/**
-* \file ZipAutoBuffer.h
-* Interface for the CZipAutoBuffer class.
-*
-* \author Tadeusz Dracz
-*/
-// Part of the ZipArchive library
-//
-// Copyright (C) 2000 - 2001 Tadeusz Dracz.
+///////////////////////////////////////////////////////////////////////////////
+// $Workfile: ZipAutoBuffer.h $
+// $Archive: /ZipArchive/ZipAutoBuffer.h $
+// $Date$ $Author$
+////////////////////////////////////////////////////////////////////////////////
+// This source file is part of the ZipArchive library source distribution and
+// is Copyright 2000-2003 by Tadeusz Dracz (http://www.artpol-software.com/)
+//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
@@ -15,6 +14,11 @@
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
+/**
+* \file ZipAutoBuffer.h
+* Interface for the CZipAutoBuffer class.
+*
+*/
#if !defined(AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_)
#define AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_
@@ -23,16 +27,27 @@
#pragma once
#endif // _MSC_VER > 1000
+#include "ZipExport.h"
/**
A smart buffer freeing its contents on destruction.
*/
-ZEXPORT class CZipAutoBuffer
+class ZIP_API CZipAutoBuffer
{
public:
operator char*()
{
return m_pBuffer;
}
+#ifndef __BORLANDC__
+ operator const char*() const // Borland seems to have problems with this
+ {
+ return m_pBuffer;
+ }
+#endif
+
+
+
+
// may produce ambiguity on some compilers
// operator const char*() const
@@ -61,3 +76,4 @@ protected:
};
#endif // !defined(AFX_ZIPAUTOBUFFER_H__DEC28C20_83FE_11D3_B7C3_EDEC47A8A86C__INCLUDED_)
+
\ No newline at end of file
diff --git a/harbour/contrib/hbzlib/zipinternalinfo.cpp b/harbour/contrib/hbzlib/include/zipbaseexception.h
similarity index 54%
rename from harbour/contrib/hbzlib/zipinternalinfo.cpp
rename to harbour/contrib/hbzlib/include/zipbaseexception.h
index a4ded567cc..6eb4b00719 100644
--- a/harbour/contrib/hbzlib/zipinternalinfo.cpp
+++ b/harbour/contrib/hbzlib/include/zipbaseexception.h
@@ -1,7 +1,11 @@
-// ZipInternalInfo.cpp: implementation of the CZipInternalInfo class.
-// Part of the ZipArchive library
-//
-// Copyright (C) 2000 - 2001 Tadeusz Dracz.
+////////////////////////////////////////////////////////////////////////////////
+// $Workfile: ZipBaseException.h $
+// $Archive: /ZipArchive_STL/ZipBaseException.h $
+// $Date$ $Author$
+////////////////////////////////////////////////////////////////////////////////
+// This source file is part of the ZipArchive library source distribution and
+// is Copyright 2000-2003 by Tadeusz Dracz (http://www.artpol-software.com/)
+//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
@@ -10,24 +14,9 @@
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
-#include "stdafx.h"
-#include "zipinternalinfo.h"
+#ifndef __ZIPBASEEXCEPTION_H__
+#define __ZIPBASEEXCEPTION_H__
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
+typedef std::exception CZipBaseException;
-CZipInternalInfo::CZipInternalInfo()
-{
- m_iBufferSize = 16384;
-}
-
-CZipInternalInfo::~CZipInternalInfo()
-{
-
-}
-
-void CZipInternalInfo::Init()
-{
- m_pBuffer.Allocate(m_iBufferSize);
-}
+#endif //__ZIPBASEEXCEPTION_H__
diff --git a/harbour/contrib/hbzlib/zipcentraldir.h b/harbour/contrib/hbzlib/include/zipcentraldir.h
similarity index 50%
rename from harbour/contrib/hbzlib/zipcentraldir.h
rename to harbour/contrib/hbzlib/include/zipcentraldir.h
index 0337dc6acc..c7c6132ec2 100644
--- a/harbour/contrib/hbzlib/zipcentraldir.h
+++ b/harbour/contrib/hbzlib/include/zipcentraldir.h
@@ -1,12 +1,11 @@
-/**
-* \file ZipCentralDir.h
-* Interface for the CZipCentralDir class.
-*
-* \author Tadeusz Dracz
-*/
-// Part of the ZipArchive library
-//
-// Copyright (C) 2000 - 2001 Tadeusz Dracz.
+////////////////////////////////////////////////////////////////////////////////
+// $Workfile: ZipCentralDir.h $
+// $Archive: /ZipArchive/ZipCentralDir.h $
+// $Date$ $Author$
+////////////////////////////////////////////////////////////////////////////////
+// This source file is part of the ZipArchive library source distribution and
+// is Copyright 2000-2003 by Tadeusz Dracz (http://www.artpol-software.com/)
+//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
@@ -15,48 +14,112 @@
// For the licensing details see the file License.txt
////////////////////////////////////////////////////////////////////////////////
+/**
+* \file ZipCentralDir.h
+* Interface for the CZipCentralDir class.
+*
+*/
+
#if !defined(AFX_CENTRALDIR_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_)
#define AFX_CENTRALDIR_H__859029E8_8927_4717_9D4B_E26E5DA12BAE__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
+
+#if (_MSC_VER > 1000) && (defined ZIP_HAS_DLL)
+ #pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class
+#endif
+
#include "zipexception.h"
#include "zipfileheader.h"
#include "zipautobuffer.h"
#include "zipcollections.h"
#include "zipcompatibility.h"
-/**
- Used in fast finding files by the filename.
- \see CZipCentralDir::m_findarray
- \see CZipArchive::FindFile
-*/
-ZEXPORT struct CZipFindFast
-{
- CZipFindFast()
- {
- m_uIndex = 0;
- m_pHeader= NULL;
- }
- CZipFindFast(CZipFileHeader* pHeader, WORD uIndex):m_pHeader(pHeader), m_uIndex(uIndex){}
- /**
- We extract a name from it.
- */
- CZipFileHeader* m_pHeader;
-
- /**
- The index in the central directory of the \e m_pHeader.
- */
- WORD m_uIndex;
-};
+#include "ZipExport.h"
+#define ZIPARCHIVE_DATADESCRIPTOR_LEN 12
/**
A class representing the central directory record in the archive.
*/
-ZEXPORT class CZipCentralDir
+class ZIP_API CZipCentralDir
{
-
public:
+ /**
+ Used in fast finding files by the filename.
+ A structure for the internal use only.
+ \see CZipCentralDir::m_findarray
+ \see CZipArchive::GetFindFastElement
+ \see CZipArchive::FindFile
+ \see CZipArchive::EnableFindFast
+ */
+ struct ZIP_API CZipFindFast
+ {
+ CZipFindFast()
+ {
+ m_uIndex = 0;
+ m_pHeader= NULL;
+ }
+ CZipFindFast(CZipFileHeader* pHeader, WORD uIndex):m_pHeader(pHeader), m_uIndex(uIndex){}
+ /**
+ A pointer to the structure in CZipCentralDir. We extract a name from it.
+ */
+ CZipFileHeader* m_pHeader;
+
+ /**
+ The index in the central directory of the \e m_pHeader.
+ */
+ WORD m_uIndex;
+ };
+
+
+ /**
+ Stores general information about the central directory record.
+ */
+ struct ZIP_API Info
+ {
+ DWORD m_uCentrDirPos; ///< the position of the beginning of the central directory (as located by #Locate)
+ DWORD m_uBytesBeforeZip;///< The number of bytes before the actual zip archive in a file. It is non-zero for self-extracting archives.
+ WORD m_uThisDisk; ///< number of the disk with the central directory end record (the number of disks in the disk-spanning archive)
+ WORD m_uDiskWithCD; ///< number of the disk with the start of the central directory
+ WORD m_uDiskEntriesNo; ///< total number of entries in the central dir on this disk
+ WORD m_uEntriesNumber; ///< total number of entries in the central dir
+ DWORD m_uSize; ///< size of the central directory (valid only if #m_bOnDisk is \c true; use #GetSize instead)
+ DWORD m_uOffset; ///< offset of start of central directory with respect to the starting disk number
+ ///< (as written in the central directory record);
+ ///< valid only if #m_bOnDisk is \c true
+ bool m_bOnDisk; ///< \c true if the central directory is physically present in the archive
+#if !defined(__GNUC__)
+ protected:
+ friend CZipCentralDir;
+#endif
+
+ bool CheckIfOK_1()
+ {
+ return ((DWORD)m_uCentrDirPos >= m_uOffset + m_uSize);
+ }
+ void SetBytesBeforeZip(bool bIsSpan)
+ {
+ m_uBytesBeforeZip = bIsSpan ? 0 : m_uCentrDirPos - m_uSize - m_uOffset;
+ }
+ bool CheckIfOK_2()
+ {
+ return (m_uSize || !m_uEntriesNumber) && (m_uEntriesNumber || !m_uSize);
+ }
+ void DiskChange(int iCurrentDisk)
+ {
+ m_uThisDisk = (WORD)iCurrentDisk;
+ if (m_uEntriesNumber)
+ {
+ m_uDiskEntriesNo = 0;
+ }
+ else
+ {
+ m_uDiskWithCD = m_uThisDisk;
+ m_uOffset = 0;
+ }
+ }
+ };
CZipCentralDir();
virtual ~CZipCentralDir();
@@ -64,12 +127,6 @@ public:
static char m_gszSignature[]; ///< central dir signature
char m_szSignature[4]; ///< end of central dir signature (must be 0x06054b50)
- WORD m_uThisDisk; ///< number of this disk
- WORD m_uDiskWithCD; ///< number of the disk with the start of the central directory
- WORD m_uDiskEntriesNo; ///< total number of entries in the central dir on this disk
- WORD m_uEntriesNumber; ///< total number of entries in the central dir
- DWORD m_uSize; ///< size of the central directory
- DWORD m_uOffset; ///< offset of start of central directory with respect to the starting disk number
CZipAutoBuffer m_pszComment; ///< the archive comment
CZipAutoBuffer m_pLocalExtraField; ///< a local extra field
@@ -100,16 +157,48 @@ public:
a zero-based index
\return \c true if the file with the given index exists inside the archive; otherwise \c false;
*/
- bool IsValidIndex(int uIndex);
+ bool IsValidIndex(int uIndex)const;
/**
Remove the file header from the central directory.
- \param uIndex
- a zero-based index of the file header to remove
+ \param pHeader
+ the header to remove
+ \param iIndex if index is not known set it to -1
+ \param bShift
\note Throws exceptions.
*/
- void RemoveFile(WORD uIndex);
+ void RemoveFile(CZipFileHeader* pHeader, int iIndex = -1, bool bShift = true);
+
+ /**
+ Remove last file from the central directory.
+
+ */
+ void RemoveLastFile(CZipFileHeader* pHeader = NULL, int iIndex = -1)
+ {
+ if (iIndex == -1)
+ {
+ iIndex = m_headers.GetSize() - 1;
+ if (iIndex == -1)
+ return;
+ }
+ if (!pHeader)
+ pHeader = m_headers[iIndex];
+ DWORD uNewSize = pHeader->m_uOffset + GetBytesBefore();
+ // then remove
+ RemoveFile(pHeader, iIndex);
+
+ m_pStorage->Flush();
+ m_pStorage->m_pFile->SetLength(uNewSize);
+ m_info.m_bOnDisk = false; // it is true when AutoFlush is set to true
+ }
+
+
+ /**
+ Remove all files
+ \note Throws exceptions.
+ */
+ void RemoveAll();
/**
Cleanup the structure.
\param bEverything
@@ -124,10 +213,27 @@ public:
/**
Add a new file to the central directory.
\param header
- copy data from it to the new file header
+ copy data from it to the new file header
+ \param iReplaceIndex if different from -1, the index of the file to be replaced
+ \return the pointer to the new header
\note Throws exceptions.
*/
- void AddNewFile(const CZipFileHeader & header);
+ CZipFileHeader* AddNewFile(const CZipFileHeader & header, int iReplaceIndex = -1);
+
+ /**
+ return the header filename, converted if needed
+ */
+ CZipString GetProperHeaderFileName(const CZipFileHeader* pHeader) const
+ {
+ if (!m_bConvertAfterOpen)
+ {
+ CZipFileHeader fh = *pHeader;
+ ConvertFileName(true, false, &fh);
+ return fh.GetFileName();
+ }
+ else
+ return pHeader->GetFileName();
+ }
/**
Remove physically the central directory from the archive.
@@ -141,14 +247,16 @@ public:
\param bWhole
if \c true, include the size of the file headers
\return the size of the central directory
+ \see CZipArchive::GetCentralDirSize
*/
- DWORD GetSize(bool bWhole = false);
+ DWORD GetSize(bool bWhole = false) const;
/**
Close a file inside archive opened for reading.
+ \param bAfterException \c true if closing after exception
\note Throws exceptions.
*/
- void CloseFile();
+ void CloseFile(bool bAfterException = false);
/**
Close a file inside archive opened for reading.
@@ -160,20 +268,39 @@ public:
Write the central directory to the archive.
\note Throws exceptions.
*/
- void Write();
+ void Write(CZipActionCallback* pCallback);
+ /**
+ \see CZipArchive::EnableFindFast
+ */
+ void EnableFindFast(bool bEnable, bool bCaseSensitive);
+
+ /**
+ \see CZipArchive::FindFile
+ \note \e bSporadically set to \c false rebuilds #m_findarray if necessary
+ */
+ int FindFile(LPCTSTR lpszFileName, bool bCaseSensitive, bool bSporadically, bool bFileNameOnly);
+
+
+ /**
+ \see CZipArchive::GetFindFastIndex
+ */
+ int GetFindFastIndex(int iFindFastIndex)const
+ {
+ if (!IsValidIndex(iFindFastIndex) || !m_bFindFastEnabled)
+ {
+ // ASSERT(FALSE); //
+ return -1;
+ }
+
+ return m_findarray[iFindFastIndex].m_uIndex;
+ }
/**
Points to CZipArchive::m_storage.
*/
CZipStorage* m_pStorage;
-
- DWORD m_uCentrDirPos; ///< the position of the beginning of the central directory
- /**
- The count of bytes before the actual zip archive in a file.
- It is non-zero for self-extracting archives.
- */
- DWORD m_uBytesBeforeZip;
+
/**
The size of the buffer used in searching for the central dir.
@@ -185,55 +312,24 @@ public:
int m_iBufferSize;
- /**
- Used in fast finding files by the filename.
- \see CZipFindFast
- \see m_bFindFastEnabled
- \see CZipArchive::FindFile
- */
- CZipFindFastArray m_findarray;
- typedef CZipPtrList::iterator CZipFindFastLstIter;
- /**
- If \c true, the there is an additional array build, to speed up the
- finding process
- CZipArchive::FindFile uses this array to perform a
- binary search.
- \b Default: \c false
- \see CZipArchive::EnableFindFast
- \see CZipArchive::FindFile
- \see CZipCentralDir::m_findarray
- */
- bool m_bFindFastEnabled;
-
-/**
- Clear #m_findarray contents and free memory.
-*/
-/**
- Build #m_findarray.
-*/
- void BuildFindFastArray();
/**
Holds all the files inside archive info.
\see CZipFileHeader
*/
- CZipPtrList m_headers;
- typedef CZipPtrList::iterator CZipFileHdrLstIter;
-
-
-
- /**
- \name Helpers
- Helper methods to operate on the CZipPtrList
-
- */
- //@{
+ CZipArray m_headers;
+
+ CZipFileHeader* operator[](int iIndex)
+ {
+ return m_headers[iIndex];
+ }
+ const CZipFileHeader* operator[](int iIndex) const
+ {
+ return m_headers[iIndex];
+ }
+
- CZipFileHeader* operator[](int iIndex);
- CZipFileHdrLstIter GetIterator(int iIndex);
- CZipFileHeader* GetFileHeader(const CZipFileHdrLstIter &iterator);
- //@}
/**
- If \c true, the conversion of the filenames takes
place after opening the archive (after reading the central directory
@@ -241,16 +337,18 @@ public:
the archive.
- If \c false, the conversion takes place on each call to CZipArchive::GetFileInfo
+ Change is value with CZipArchive::SetConvertAfterOpen.
+
Set it to \c true when you plan to use CZipArchive::FindFile or get the stored files information.
- Set it to \c false when you plan mostly to only modify the archive.
+ Set it to \c false when you plan mostly to modify the archive.
\b Default: \c true
\note Set it before opening the archive.
+ \see CZipArchive::SetConvertAfterOpen
\see ConvertFileName
*/
bool m_bConvertAfterOpen;
-
-
+
/**
Convert the filename of the CZipFileHeader depending on the current system
@@ -266,7 +364,7 @@ public:
\see ZipCompatibility::FileNameUpdate
\see m_bConvertAfterOpen
*/
- void ConvertFileName(bool bFromZip, bool bAfterOpen, CZipFileHeader* pHeader = NULL)
+ void ConvertFileName(bool bFromZip, bool bAfterOpen, CZipFileHeader* pHeader = NULL) const
{
if (bAfterOpen != m_bConvertAfterOpen)
return;
@@ -289,16 +387,77 @@ public:
\param lpszFileName
the name of the file to find, must be exactly the same (apart from case)
as it appears in the archive
- \param bCaseSensitive
- \c true if perform a case sensitive search
\return the index in #m_findarray with the appropriate CZipFindFast structure
or \c -1 if there is no file with the given name
\see CZipArchive::FindFile
*/
- int FindFileNameIndex(LPCTSTR lpszFileName, bool bCaseSensitive);
+ int FindFileNameIndex(LPCTSTR lpszFileName) const;
-
+ DWORD GetBytesBefore() const {return m_info.m_uBytesBeforeZip;}
+ /**
+ Get the information about the central directory
+ */
+ void GetInfo(Info& info) const {info = m_info;}
+ /**
+ \return the value of m_bFindFastEnabled
+ */
+ bool IsFindFastEnabled(){return m_bFindFastEnabled;}
+ /**
+ Called by CZipArchive::RenameFile
+ */
+ void RenameFile(WORD uIndex, LPCTSTR lpszNewName);
protected:
+ /**
+ Sort the files inside the archive headers by the order in the archive.
+ */
+ void SortHeaders();
+ static int CompareHeaders(const void *pArg1, const void *pArg2)
+ {
+ CZipFileHeader* pw1 = *(CZipFileHeader**)pArg1;
+ CZipFileHeader* pw2 = *(CZipFileHeader**)pArg2;
+ if ((pw1->m_uOffset < pw2->m_uOffset && pw1->m_uDiskStart == pw2->m_uDiskStart)
+ || (pw1->m_uDiskStart < pw2->m_uDiskStart))
+ return -1;
+ else if ((pw1->m_uOffset > pw2->m_uOffset && pw1->m_uDiskStart == pw2->m_uDiskStart)
+ || (pw1->m_uDiskStart > pw2->m_uDiskStart))
+ return 1;
+ else
+ {
+ ASSERT(FALSE);
+ // two files with the same offsets on the same disk???
+ CZipException::Throw(CZipException::badZipFile);
+ return 0; // just for the compiler comfort
+ }
+ }
+
+
+/**
+ Build #m_findarray.
+*/
+ void BuildFindFastArray( bool bCaseSensitive );
+
+ /**
+ Used in fast finding files by the filename.
+ \see CZipFindFast
+ \see m_bFindFastEnabled
+ \see CZipArchive::FindFile
+ */
+ CZipArray m_findarray;
+
+ /**
+ If \c true, the there is an additional array build, to speed up the
+ finding process
+ CZipArchive::FindFile uses this array to perform a
+ binary search.
+ \b Default: \c false
+ \see CZipArchive::EnableFindFast
+ \see CZipArchive::FindFile
+ \see CZipCentralDir::m_findarray
+ */
+ bool m_bFindFastEnabled;
+
+
+
/**
The \e lpszFileName and \e bCaseSensitive arguments
are the same as in the #FindFileNameIndex. The function get CZipFindFast
@@ -307,25 +466,40 @@ protected:
\param lpszFileName
\param uIndex
the index from #m_findarray
- \param bCaseSensitive
\return
- 0 if the filenames are the same
- < 0 if the filename stored in the array is less than \e lpszFileName
- > 0 if the filename stored in the array is greater than \e lpszFileName
*/
-ZIPINLINE int CompareElement(LPCTSTR lpszFileName, WORD uIndex, bool bCaseSensitive);
-
+ int CompareElement(LPCTSTR lpszFileName, WORD uIndex) const
+ {
+ return (m_findarray[uIndex].m_pHeader->GetFileName().*m_pCompare)(lpszFileName);
+ }
/**
Insert a new CZipFindFast element to the #m_findarray.
Initialize CZipFindFast object with \e pHeader and \e uIndex values.
- \param pHeader
- \param uIndex
*/
void InsertFindFastElement(CZipFileHeader* pHeader, WORD uIndex);
+
+
+
/**
- \c true if the central directory is in physically present in the archive
+ A compare function (Collate or CollateNoCase) set once so as not
+ to check every time which one to use
+ ZIPSTRINGCOMPARE is defined in CZipString.h as:
+ typedef int (CZipString::*ZIPSTRINGCOMPARE)( LPCTSTR ) const;
*/
- bool m_bOnDisk;
+ ZIPSTRINGCOMPARE m_pCompare;
+
+ /**
+ The way the m_findarray is sorted
+ */
+ bool m_bCaseSensitive;
+
+ /**
+ \see Info
+ */
+ Info m_info;
/**
\return the location of the beginning of the central dir end record in the archive
@@ -358,7 +532,7 @@ ZIPINLINE int CompareElement(LPCTSTR lpszFileName, WORD uIndex, bool bCaseSens
Write the file headers to the archive.
\note Throws exceptions.
*/
- void WriteHeaders();
+ void WriteHeaders(CZipActionCallback* pCallback, bool bOneDisk);
/**
Write the central directory end record.
\return the size of the record
@@ -371,7 +545,9 @@ ZIPINLINE int CompareElement(LPCTSTR lpszFileName, WORD uIndex, bool bCaseSens
\param err
\see CZipException::Throw
*/
- void ThrowError(int err);
+ void ThrowError(int err) const;
+
+
};
diff --git a/harbour/contrib/hbzlib/include/zipcollections.h b/harbour/contrib/hbzlib/include/zipcollections.h
new file mode 100644
index 0000000000..002d3d9cf4
--- /dev/null
+++ b/harbour/contrib/hbzlib/include/zipcollections.h
@@ -0,0 +1,180 @@
+////////////////////////////////////////////////////////////////////////////////
+// $Workfile: ZipCollections.h $
+// $Archive: /ZipArchive_STL/ZipCollections.h $
+// $Date$ $Author$
+////////////////////////////////////////////////////////////////////////////////
+// This source file is part of the ZipArchive library source distribution and
+// is Copyright 2000-2003 by Tadeusz Dracz (http://www.artpol-software.com/)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// For the licensing details see the file License.txt
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef ZIPCOLLECTIONS_DOT_H
+#define ZIPCOLLECTIONS_DOT_H
+
+#if _MSC_VER > 1000
+ #pragma warning( push, 3 ) // STL "requirements"
+ #pragma warning (disable : 4284) //return type for 'identifier::operator >' is not a UDT or reference to a UDT. Will produce errors if applied using infix notation
+ #pragma warning (disable : 4018) //'expression' : signed/unsigned mismatch
+#endif
+
+#include
+#include
+#include