Merge branch 'develop' into OpenSSLBuild

This commit is contained in:
Alex Fabijanic 2015-05-21 19:46:58 -05:00
commit 995832639e
57 changed files with 1428 additions and 493 deletions

View File

@ -6,10 +6,10 @@
# ENABLE_{COMPONENT}
# ENABLE_TESTS
project(Poco)
cmake_minimum_required(VERSION 3.0.0)
project(Poco)
file(STRINGS "${PROJECT_SOURCE_DIR}/libversion" SHARED_LIBRARY_VERSION)
# Read the version information from the VERSION file
@ -53,19 +53,6 @@ if (CMAKE_BUILD_TYPE STREQUAL "")
set( CMAKE_BUILD_TYPE "RelWithDebInfo" )
endif()
# http://www.cmake.org/Wiki/CMake_Useful_Variables :
# CMAKE_BUILD_TYPE
# Choose the type of build. CMake has default flags for these:
#
# * None (CMAKE_C_FLAGS or CMAKE_CXX_FLAGS used)
# * Debug (CMAKE_C_FLAGS_DEBUG or CMAKE_CXX_FLAGS_DEBUG)
# * Release (CMAKE_C_FLAGS_RELEASE or CMAKE_CXX_FLAGS_RELEASE)
# * RelWithDebInfo (CMAKE_C_FLAGS_RELWITHDEBINFO or CMAKE_CXX_FLAGS_RELWITHDEBINFO
# * MinSizeRel (CMAKE_C_FLAGS_MINSIZEREL or CMAKE_CXX_FLAGS_MINSIZEREL)
# For Debug build types, append a "d" to the library names.
set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Set debug library postfix" FORCE)
# Include some common macros to simpilfy the Poco CMake files
include(PocoMacros)
@ -102,7 +89,12 @@ option(POCO_STATIC
option(POCO_UNBUNDLED
"Set to OFF|ON (default is OFF) to control linking dependencies as external" OFF)
# Uncomment from next two lines to force statitc or dynamic library, default is autodetection
if(MSVC)
option(POCO_MT
"Set to OFF|ON (default is OFF) to control build of POCO as /MT instead of /MD" OFF)
endif()
# Uncomment from next two lines to force static or dynamic library, default is autodetection
if(POCO_STATIC)
add_definitions( -DPOCO_STATIC -DPOCO_NO_AUTOMATIC_LIBS)
set( LIB_MODE STATIC )
@ -127,58 +119,7 @@ else ()
message(STATUS "Build with using internal copy of sqlite, libz, pcre, expat, ...")
endif ()
include(CheckTypeSize)
find_package(Cygwin)
# OS Detection
if(WIN32)
add_definitions( -DPOCO_OS_FAMILY_WINDOWS -DUNICODE -D_UNICODE)
#set(SYSLIBS iphlpapi gdi32 odbc32)
endif(WIN32)
if (UNIX AND NOT ANDROID )
add_definitions( -DPOCO_OS_FAMILY_UNIX )
# Standard 'must be' defines
if (APPLE)
add_definitions( -DPOCO_HAVE_IPv6 -DPOCO_NO_STAT64)
set(SYSLIBS dl)
else (APPLE)
add_definitions( -D_XOPEN_SOURCE=500 -D_REENTRANT -D_THREAD_SAFE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64)
set(SYSLIBS pthread dl rt)
endif (APPLE)
endif(UNIX AND NOT ANDROID )
if (CMAKE_SYSTEM MATCHES "SunOS")
add_definitions( -DPOCO_OS_FAMILY_UNIX )
# Standard 'must be' defines
add_definitions( -D_XOPEN_SOURCE=500 -D_REENTRANT -D_THREAD_SAFE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 )
set(SYSLIBS pthread socket xnet nsl resolv rt dl)
endif(CMAKE_SYSTEM MATCHES "SunOS")
if (CMAKE_COMPILER_IS_MINGW)
add_definitions(-DWC_NO_BEST_FIT_CHARS=0x400 -DPOCO_WIN32_UTF8)
add_definitions(-D_WIN32 -DMINGW32 -DWINVER=0x500 -DODBCVER=0x0300 -DPOCO_THREAD_STACK_SIZE)
endif (CMAKE_COMPILER_IS_MINGW)
if (CYGWIN)
# add_definitions(-DWC_NO_BEST_FIT_CHARS=0x400 -DPOCO_WIN32_UTF8)
endif (CYGWIN)
# SunPro C++
if (${CMAKE_CXX_COMPILER_ID} MATCHES "SunPro")
add_definitions( -D_BSD_SOURCE -library=stlport4)
endif (${CMAKE_CXX_COMPILER_ID} MATCHES "SunPro")
# iOS
if (IOS)
add_definitions( -DPOCO_HAVE_IPv6 -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_STAT64 -DPOCO_NO_SHAREDLIBS -DPOCO_NO_NET_IFTYPES )
endif(IOS)
#Android
if (ANDROID)
add_definitions( -DPOCO_ANDROID -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_WSTRING -DPOCO_NO_SHAREDMEMORY )
endif(ANDROID)
include(DefinePlatformSpecifc)
# Collect the built libraries and include dirs, the will be used to create the PocoConfig.cmake file
set(Poco_COMPONENTS "")
@ -330,7 +271,17 @@ message(STATUS "CMake ${CMAKE_VERSION} successfully configured ${PROJECT_NAME} u
message(STATUS "Installation target path: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "C_FLAGS: =${CMAKE_C_FLAGS}")
message(STATUS "CMAKE_C_FLAGS_DEBUG:=${CMAKE_C_FLAGS_DEBUG}")
message(STATUS "CMAKE_C_FLAGS_RELEASE:=${CMAKE_C_FLAGS_RELEASE}")
message(STATUS "CMAKE_C_FLAGS_MINSIZEREL:=${CMAKE_C_FLAGS_MINSIZEREL}")
message(STATUS "CMAKE_C_FLAGS_RELWITHDEBINFO:=${CMAKE_C_FLAGS_RELWITHDEBINFO}")
message(STATUS "")
message(STATUS "")
message(STATUS "CXX_FLAGS:=${CMAKE_CXX_FLAGS}")
message(STATUS "CMAKE_CXX_FLAGS_DEBUG:=${CMAKE_CXX_FLAGS_DEBUG}")
message(STATUS "CMAKE_CXX_FLAGS_RELEASE:=${CMAKE_CXX_FLAGS_RELEASE}")
message(STATUS "CMAKE_CXX_FLAGS_MINSIZEREL:=${CMAKE_CXX_FLAGS_MINSIZEREL}")
message(STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO:=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
foreach(component ${Poco_COMPONENTS})
message(STATUS "Building: ${component}")

View File

@ -44,7 +44,7 @@ namespace Crypto {
class Crypto_API OpenSSLInitializer
/// Initializes the OpenSSL library.
/// Initalizes the OpenSSL library.
///
/// The class ensures the earliest initialization and the
/// latest shutdown of the OpenSSL library.
@ -68,6 +68,8 @@ public:
static void enableFIPSMode(bool enabled);
// Enable or disable FIPS mode. If FIPS is not available, this method doesn't do anything.
static void disableSSLInitialization(); // Call if OpenSSL is already being initialized by another component before constructing any OpenSSLInitializers.
protected:
enum
{
@ -84,6 +86,7 @@ protected:
private:
static Poco::FastMutex* _mutexes;
static Poco::AtomicCounter _rc;
static bool _disableSSLInitialization;
};
@ -110,6 +113,11 @@ inline void OpenSSLInitializer::enableFIPSMode(bool /*enabled*/)
}
#endif
inline void OpenSSLInitializer::disableSSLInitialization()
{
_disableSSLInitialization = true;
}
} } // namespace Poco::Crypto

View File

@ -36,7 +36,7 @@ namespace Crypto {
Poco::FastMutex* OpenSSLInitializer::_mutexes(0);
Poco::AtomicCounter OpenSSLInitializer::_rc;
bool OpenSSLInitializer::_disableSSLInitialization = false;
OpenSSLInitializer::OpenSSLInitializer()
{
@ -64,15 +64,18 @@ void OpenSSLInitializer::initialize()
#if OPENSSL_VERSION_NUMBER >= 0x0907000L
OPENSSL_config(NULL);
#endif
if(! _disableSSLInitialization) {
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
}
char seed[SEEDSIZE];
RandomInputStream rnd;
rnd.read(seed, sizeof(seed));
RAND_seed(seed, SEEDSIZE);
if(CRYPTO_get_locking_callback() == NULL) {
int nMutexes = CRYPTO_num_locks();
_mutexes = new Poco::FastMutex[nMutexes];
CRYPTO_set_locking_callback(&OpenSSLInitializer::lock);
@ -84,30 +87,47 @@ void OpenSSLInitializer::initialize()
// "If the application does not register such a callback using CRYPTO_THREADID_set_callback(),
// then a default implementation is used - on Windows and BeOS this uses the system's
// default thread identifying APIs"
#ifndef OPENSSL_NO_DEPRECATED
CRYPTO_set_id_callback(&OpenSSLInitializer::id);
#else
CRYPTO_THREADID tid;
CRYPTO_THREADID_set_numeric(&tid, OpenSSLInitializer::id());
#endif /* OPENSSL_NO_DEPRECATED */
#endif
CRYPTO_set_dynlock_create_callback(&OpenSSLInitializer::dynlockCreate);
CRYPTO_set_dynlock_lock_callback(&OpenSSLInitializer::dynlock);
CRYPTO_set_dynlock_destroy_callback(&OpenSSLInitializer::dynlockDestroy);
}
}
}
void OpenSSLInitializer::uninitialize()
{
if (--_rc == 0)
{
EVP_cleanup();
ERR_free_strings();
if(_mutexes != NULL) {
CRYPTO_set_dynlock_create_callback(0);
CRYPTO_set_dynlock_lock_callback(0);
CRYPTO_set_dynlock_destroy_callback(0);
CRYPTO_set_locking_callback(0);
#ifndef POCO_OS_FAMILY_WINDOWS
#ifndef OPENSSL_NO_DEPRECATED
CRYPTO_set_id_callback(0);
#else
CRYPTO_THREADID tid;
CRYPTO_THREADID_set_numeric(&tid, 0);
#endif /* OPENSSL_NO_DEPRECATED */
#endif
delete [] _mutexes;
}
if(! _disableSSLInitialization) {
EVP_cleanup();
ERR_free_strings();
CONF_modules_free();
}
}
}
void OpenSSLInitializer::lock(int mode, int n, const char* file, int line)

View File

@ -117,7 +117,7 @@ public:
/// of this Transaction object.
template <typename T>
void transact(T& t)
void transact(const T& t)
/// Executes the transactor and, unless transactor throws an exception,
/// commits the transaction.
{

49
FAQ.md Normal file
View File

@ -0,0 +1,49 @@
# POCO Frequently Asked Questions
---
## Generic Questions
**Q:** How do I do [xyz] with POCO?
**A:** It depends on what exactly [xyz] is. POCO community is more than happy to help newcomers and experienced C++ programmers alike. There are, however, certain limitations as to how far we are willing to go as well as expectations we have for people asking questions:
- First and foremost, read the relevant [documentation](http://pocoproject.org/documentation/index.html)
- Please be patient and respectful; we answer questions free of charge and our time is at least as valuable as yours.
- Please do [your share of work before asking](#resources); since we are doing this free of charge, make sure to make it as easy as possible for us to identify the problem - it will greatly increase the chances of getting an answer.
- Please do not ask us to solve your homework, commercial or hobby project application problems; although we provide answers free of monetary charge, we do have an incentive - improving POCO for yours and our benefit. Your question may contain important information in that sense but you must demonstrate it clearly to get our attention quickly. In the process, the solution to your particular problem is often a side-effect; we are happy to help, but keep in mind - that is not our primary incentive.
- We are not here to teach you about basics of networking, XML or JSON parsing, C++ language etc.; there are many other resources to learn about those topics. Keep in mind our primary incentive (improving POCO by fixing bugs, improving usability or adding features).
- If nobody steps up to help or someone starts but chooses to stop helping you at any point, please do not get upset and/or verbally abusive; remember - we have lives and obligations and we do this free of charge, therefore owe you nothing unless you choose to enter into a contractual relationship with us to obtain needed help; we do such arrangements and you can contact us individually should you need one. Consider also that your demeanor may have caused the person helping to you to stop.
- Please spend some time studying the answers we provide; do not come back without thoroughly understanding and trying the proposed solution
<a name="resources">Resources</a> to help with asking the question right and provide code examples in an effective and productive manner:
- [Getting Started With The POCO C++ Libraries](http://pocoproject.org/docs/00200-GettingStarted.html)
- [How To Ask Questions The Smart Way](http://www.catb.org/esr/faqs/smart-questions.html)
- [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve)
--
**Q:** How do I contribute to POCO?
**A:** See [Contributing](https://github.com/pocoproject/poco/blob/develop/CONTRIBUTING.md)
## Specific Questions
**Q:** How do I build POCO on platform [xyz]?
**A:** POCO builds out-of-the-box on many platforms. See [Building portion](http://pocoproject.org/docs/00200-GettingStarted.html#7) for your platform in the [Getting Started](http://pocoproject.org/docs/00200-GettingStarted.html) document. If things don't work according to the documentation, please let us know. If you find a problem and know how to fix it, please do and send us a [pull request](https://help.github.com/articles/using-pull-requests/).
--
**Q:** Is there a coding style guide?
**A:** [Yes](http://www.appinf.com/download/CppCodingStyleGuide.pdf).
--
**Q:** Where can I find examples of POCO usage?
**A:** Every POCO library comes with a set of small, fully-functional, example applications; the samples are located in the "samples" directory of each POCO library; additionally, the knowledge on usage of POCO can also be gained by studying and running unit tests, located under "testsuite" directory for each POCO library.

View File

@ -148,11 +148,6 @@ protected:
//
#if defined(POCO_COMPILER_GCC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) && !defined(POCO_ANDROID)
GCC_DIAG_OFF(unused-local-typedefs) // supress numerous gcc warnings
#endif // POCO_COMPILER_GCC && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408)
template <bool x>
struct POCO_STATIC_ASSERTION_FAILURE;
@ -180,7 +175,7 @@ struct poco_static_assert_test
#else
#define poco_static_assert(B) \
typedef poco_static_assert_test<sizeof(POCO_STATIC_ASSERTION_FAILURE<(bool) (B)>)> \
POCO_JOIN(poco_static_assert_typedef_, __LINE__)
POCO_JOIN(poco_static_assert_typedef_, __LINE__) POCO_UNUSED
#endif

View File

@ -112,12 +112,6 @@
#endif
#ifndef __GNUC__
#define GCC_DIAG_OFF(x)
#define GCC_DIAG_ON(x)
#endif
//
// Hardware Architecture and Byte Order
//
@ -257,6 +251,13 @@
#endif
#ifdef __GNUC__
#define POCO_UNUSED __attribute__((unused))
#else
#define POCO_UNUSED
#endif // __GNUC__
#if !defined(POCO_ARCH)
#error "Unknown Hardware Architecture."
#endif

View File

@ -44,38 +44,6 @@
#endif
//
// GCC diagnostics enable/disable by Patrick Horgan, see
// http://dbp-consulting.com/tutorials/SuppressingGCCWarnings.html
// use example: GCC_DIAG_OFF(unused-variable)
//
#ifdef __GNUC__
#if defined(POCO_COMPILER_GCC) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) && !defined(POCO_NO_GCC_DIAG)
#ifdef GCC_DIAG_OFF
#undef GCC_DIAG_OFF
#endif
#ifdef GCC_DIAG_ON
#undef GCC_DIAG_ON
#endif
#define GCC_DIAG_STR(s) #s
#define GCC_DIAG_JOINSTR(x,y) GCC_DIAG_STR(x ## y)
#define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x)
#define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x)
#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
#define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(push) \
GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x))
#define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(pop)
#else
#define GCC_DIAG_OFF(x) GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x))
#define GCC_DIAG_ON(x) GCC_DIAG_PRAGMA(warning GCC_DIAG_JOINSTR(-W,x))
#endif
#else
#define GCC_DIAG_OFF(x)
#define GCC_DIAG_ON(x)
#endif
#endif // __GNUC__
//
// No syslog.h on QNX/BB10
//

View File

@ -225,7 +225,6 @@ void ThreadImpl::setAffinityImpl(int cpu)
int ThreadImpl::getAffinityImpl() const
{
int cpuSet = -1;
int cpuCount = Environment::processorCount();
#if defined (POCO_OS_FAMILY_UNIX) && POCO_OS != POCO_OS_MAC_OS_X
#ifdef HAVE_PTHREAD_SETAFFINITY_NP
cpu_set_t cpuset;
@ -237,6 +236,7 @@ int ThreadImpl::getAffinityImpl() const
if (pthread_getaffinity_np(_pData->thread, &cpuset) != 0)
throw SystemException("Failed to get affinity", errno);
#endif
int cpuCount = Environment::processorCount();
for (int i = 0; i < cpuCount; i++)
{
if (CPU_ISSET(i, &cpuset))
@ -263,6 +263,7 @@ int ThreadImpl::getAffinityImpl() const
throw SystemException("Failed to get affinity", errno);
}
cpuSet = policy.affinity_tag;
int cpuCount = Environment::processorCount();
if (cpuSet >= cpuCount)
cpuSet = -1;

View File

@ -18,11 +18,12 @@
#include "Poco/Bugcheck.h"
#include <vector>
GCC_DIAG_OFF(unused-but-set-variable)
#if defined(_MSC_VER) && _MSC_VER < 1400
#pragma warning(disable:4800)//forcing value to bool 'true' or 'false'
#endif
using namespace Poco;

View File

@ -18,7 +18,6 @@
#include "Poco/Exception.h"
#include "TestPlugin.h"
GCC_DIAG_OFF(unused-variable)
using Poco::ClassLoader;
using Poco::Manifest;

View File

@ -31,7 +31,6 @@
#include <vector>
#include <cstring>
GCC_DIAG_OFF(unused-variable)
using Poco::Bugcheck;
using Poco::Exception;

View File

@ -19,9 +19,6 @@
#include "Poco/Exception.h"
GCC_DIAG_OFF(unused-variable)
using Poco::Timestamp;
using Poco::DateTime;
using Poco::Timespan;

View File

@ -21,7 +21,6 @@
#include <fstream>
#include <set>
GCC_DIAG_OFF(unused-variable)
using Poco::File;
using Poco::TemporaryFile;

View File

@ -17,7 +17,6 @@
#include "Poco/Exception.h"
#include <map>
GCC_DIAG_OFF(unused-variable)
using Poco::HashMap;

View File

@ -17,9 +17,6 @@
#include "Poco/NumberFormatter.h"
GCC_DIAG_OFF(unused-variable)
using namespace Poco;

View File

@ -17,7 +17,6 @@
#include "Poco/Exception.h"
#include <map>
GCC_DIAG_OFF(unused-variable)
using Poco::ListMap;

View File

@ -18,7 +18,6 @@
#include "Poco/PatternFormatter.h"
#include "Poco/AutoPtr.h"
GCC_DIAG_OFF(unused-variable)
using Poco::LoggingRegistry;
using Poco::Channel;

View File

@ -16,7 +16,6 @@
#include "Poco/NamedTuple.h"
#include "Poco/Exception.h"
GCC_DIAG_OFF(unused-but-set-variable)
using Poco::NamedTuple;
using Poco::Int8;

View File

@ -17,9 +17,6 @@
#include "Poco/NumberFormatter.h"
GCC_DIAG_OFF(unused-variable)
using namespace Poco;

View File

@ -16,7 +16,6 @@
#include "Poco/StringTokenizer.h"
#include "Poco/Exception.h"
GCC_DIAG_OFF(unused-variable)
using Poco::StringTokenizer;
using Poco::RangeException;

View File

@ -18,11 +18,12 @@
#include "Poco/Void.h"
#include <iostream>
GCC_DIAG_OFF(unused-but-set-variable)
#if defined(_MSC_VER)
# pragma warning(disable:4800) // forcing value to bool 'true' or 'false' on MSVC 71
#endif
using Poco::TypeList;
using Poco::Tuple;
using Poco::NullTypeList;

View File

@ -22,7 +22,7 @@
#include <utility>
GCC_DIAG_OFF(unused-variable)
#if defined(_MSC_VER) && _MSC_VER < 1400
#pragma warning(disable:4800)//forcing value to bool 'true' or 'false'
#endif

View File

@ -21,7 +21,6 @@
#include "Poco/Exception.h"
#include "CppUnit/TestCase.h"
GCC_DIAG_OFF(unused-but-set-variable)
class VarTest: public CppUnit::TestCase
{

View File

@ -107,7 +107,7 @@ const std::string& Object::getKey(KeyPtrList::const_iterator& iter) const
ValueMap::const_iterator end = _values.end();
for (; it != end; ++it)
{
if (&it->second == *iter) return it->first;
if (it->second == **iter) return it->first;
}
throw NotFoundException((*iter)->convert<std::string>());

View File

@ -185,7 +185,7 @@ protected:
inline Document& Document::addElement(Element::Ptr element)
{
_elements.insert(element);
_elements.push_back(element);
return *this;
}

View File

@ -33,7 +33,7 @@
#include <string>
#include <sstream>
#include <iomanip>
#include <set>
#include <list>
namespace Poco {
@ -76,17 +76,7 @@ inline std::string Element::name() const
}
class ElementComparator
{
public:
bool operator()(const Element::Ptr& s1, const Element::Ptr& s2)
{
return s1->name() < s2->name();
}
};
typedef std::set<Element::Ptr, ElementComparator> ElementSet;
typedef std::list<Element::Ptr> ElementSet;
template<typename T>

View File

@ -234,7 +234,7 @@ void sample5(Poco::MongoDB::Connection& connection)
// When orderby is needed, use 2 separate documents in the query selector
cursor.query().selector().addNewDocument("$query").add("birthyear", 1987);
cursor.query().selector().addNewDocument("$orderby").add("lastname", 0);
cursor.query().selector().addNewDocument("$orderby").add("lastname", -1);
Poco::MongoDB::ResponseMessage& response = cursor.next(connection);
while(1)
@ -410,7 +410,7 @@ void sample11(Poco::MongoDB::Connection& connection)
if ( response.hasDocuments() )
{
std::cout << "Count: " << response.documents()[0]->get<double>("n") << std::endl;
std::cout << "Count: " << response.documents()[0]->get<int>("n") << std::endl;
}
}

View File

@ -120,7 +120,7 @@ void Document::read(BinaryReader& reader)
}
element->read(reader);
_elements.insert(element);
_elements.push_back(element);
reader >> type;
}

View File

@ -410,6 +410,29 @@ void MongoDBTest::testObjectID()
}
void MongoDBTest::testCommand() {
Poco::MongoDB::Database db("team");
Poco::SharedPtr<Poco::MongoDB::QueryRequest> command = db.createCommand();
command->selector().add("create", "fixCol")
.add("capped", true)
.add("max", 1024*1024)
.add("size", 1024);
Poco::MongoDB::ResponseMessage response;
_mongo.sendRequest(*command, response);
if ( response.documents().size() > 0 )
{
Poco::MongoDB::Document::Ptr doc = response.documents()[0];
std::cout << doc->toString(2);
}
else
{
Poco::MongoDB::Document::Ptr lastError = db.getLastErrorDoc(_mongo);
std::cout << "LastError: " << lastError->toString(2) << std::endl;
fail("Didn't get a response from the command");
}
}
CppUnit::Test* MongoDBTest::suite()
{
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("MongoDBTest");
@ -425,6 +448,7 @@ CppUnit::Test* MongoDBTest::suite()
CppUnit_addTest(pSuite, MongoDBTest, testBuildInfo);
CppUnit_addTest(pSuite, MongoDBTest, testCursorRequest);
CppUnit_addTest(pSuite, MongoDBTest, testObjectID);
CppUnit_addTest(pSuite, MongoDBTest, testCommand);
return pSuite;
}

View File

@ -41,6 +41,7 @@ public:
void testConnectionPool();
void testCursorRequest();
void testObjectID();
void testCommand();
void setUp();
void tearDown();

View File

@ -18,7 +18,6 @@
#include "Poco/Net/NetException.h"
#include <sstream>
GCC_DIAG_OFF(parentheses)
using Poco::Net::HTTPResponse;
using Poco::Net::HTTPMessage;

View File

@ -24,7 +24,18 @@ set_target_properties( "${LIBNAME}"
DEFINE_SYMBOL Util_EXPORTS
)
target_link_libraries( "${LIBNAME}" JSON XML Foundation)
target_link_libraries( "${LIBNAME}" Foundation)
if (ENABLE_XML)
target_link_libraries( "${LIBNAME}" XML)
else ()
add_definitions( -DPOCO_UTIL_NO_XMLCONFIGURATION )
endif()
if (ENABLE_JSON)
target_link_libraries( "${LIBNAME}" JSON)
else ()
add_definitions( -DPOCO_UTIL_NO_JSONCONFIGURATION )
endif()
target_include_directories( "${LIBNAME}"
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>

View File

@ -38,9 +38,11 @@ class Zip_API Compress
public:
Poco::FIFOEvent<const ZipLocalFileHeader> EDone;
Compress(std::ostream& out, bool seekableOut);
Compress(std::ostream& out, bool seekableOut, bool forceZip64 = false);
/// seekableOut determines how we write the zip, setting it to true is recommended for local files (smaller zip file),
/// if you are compressing directly to a network, you MUST set it to false
/// If forceZip64 is set true then the file header is allocated with zip64 extension so that it can be updated after the file data is written
/// if seekableOut is true in case the compressed or uncompressed size exceeds 32 bits.
~Compress();
@ -103,16 +105,18 @@ private:
/// for directories.
void addFileRaw(std::istream& in, const ZipLocalFileHeader& hdr, const Poco::Path& fileName);
/// Copies an already compressed ZipEntry from in
/// copys an already compressed ZipEntry from in
private:
std::set<std::string> _storeExtensions;
std::ostream& _out;
bool _seekableOut;
bool _forceZip64;
ZipArchive::FileHeaders _files;
ZipArchive::FileInfos _infos;
ZipArchive::DirectoryInfos _dirs;
Poco::UInt32 _offset;
ZipArchive::DirectoryInfos64 _dirs64;
Poco::UInt64 _offset;
std::string _comment;
friend class Keep;
@ -123,6 +127,8 @@ private:
//
// inlines
//
inline void Compress::setZipComment(const std::string& comment)
{
_comment = comment;

View File

@ -24,6 +24,7 @@
#include "Poco/Zip/ZipLocalFileHeader.h"
#include "Poco/Zip/ZipFileInfo.h"
#include "Poco/Zip/ZipArchiveInfo.h"
#include <istream>
#include <map>
@ -43,6 +44,7 @@ public:
typedef std::map<std::string, ZipLocalFileHeader> FileHeaders;
typedef std::map<std::string, ZipFileInfo> FileInfos;
typedef std::map<Poco::UInt16, ZipArchiveInfo> DirectoryInfos;
typedef std::map<Poco::UInt32, ZipArchiveInfo64> DirectoryInfos64;
ZipArchive(std::istream& in);
/// Creates the ZipArchive from a file. Note that the in stream will be in state failed after the constructor is finished
@ -68,7 +70,7 @@ public:
private:
void parse(std::istream& in, ParseCallback& pc);
ZipArchive(const FileHeaders& entries, const FileInfos& infos, const DirectoryInfos& dirs );
ZipArchive(const FileHeaders& entries, const FileInfos& infos, const DirectoryInfos& dirs, const DirectoryInfos64& dirs64 );
private:
FileHeaders _entries;
@ -77,6 +79,8 @@ private:
/// Info generated by parsing the directory block of the zip file
DirectoryInfos _disks;
/// Stores directory info for all found disks
DirectoryInfos64 _disks64;
/// Stores directory info for all found disks
friend class Compress;
};

View File

@ -70,15 +70,19 @@ public:
/// Sets the optional Zip comment.
void setNumberOfEntries(Poco::UInt16 val);
/// Returns the number of entries on this disk
/// Sets the number of entries on this disk
void setTotalNumberOfEntries(Poco::UInt16 val);
/// Returns the total number of entries on all disks
/// Sets the total number of entries on all disks
void setCentralDirectorySize(Poco::UInt32 val);
/// Returns the size of the central directory in bytes
/// Sets the size of the central directory in bytes
void setHeaderOffset(Poco::UInt32 val);
void setCentralDirectoryOffset(Poco::UInt32 val);
/// Sets the offset of the central directory from beginning of first disk
void setHeaderOffset(std::streamoff val);
/// Sets the offset of the header in relation to the begin of this disk
std::string createHeader() const;
/// Creates a header
@ -115,6 +119,122 @@ private:
};
class Zip_API ZipArchiveInfo64
/// A ZipArchiveInfo64 stores central directory info
{
public:
static const char HEADER[ZipCommon::HEADER_SIZE];
static const char LOCATOR_HEADER[ZipCommon::HEADER_SIZE];
ZipArchiveInfo64();
/// Default constructor, everything set to zero or empty
ZipArchiveInfo64(std::istream& in, bool assumeHeaderRead);
/// Creates the ZipArchiveInfo64 by parsing the input stream.
/// If assumeHeaderRead is true we assume that the first 4 bytes were already read outside.
~ZipArchiveInfo64();
/// Destroys the ZipArchiveInfo64.
void getVersionMadeBy(int& major, int& minor);
/// The ZIP version used to create the file
void getRequiredVersion(int& major, int& minor);
/// The minimum version required to extract the data
Poco::UInt32 getDiskNumber() const;
/// Get the number of the disk where this header can be found
Poco::UInt32 getFirstDiskForDirectoryHeader() const;
/// Returns the number of the disk that contains the start of the directory header
Poco::UInt64 getNumberOfEntries() const;
/// Returns the number of entries on this disk
Poco::UInt64 getTotalNumberOfEntries() const;
/// Returns the total number of entries on all disks
Poco::UInt64 getCentralDirectorySize() const;
/// Returns the size of the central directory in bytes
std::streamoff getCentralDirectoryOffset() const;
/// Returns the offset of the central directory from beginning of first disk
std::streamoff getHeaderOffset() const;
/// Returns the offset of the header in relation to the begin of this disk
void setNumberOfEntries(Poco::UInt64 val);
/// Sets the number of entries on this disk
void setTotalNumberOfEntries(Poco::UInt64 val);
/// Sets the total number of entries on all disks
void setCentralDirectorySize(Poco::UInt64 val);
/// Set the size of the central directory in bytes
void setCentralDirectoryOffset(Poco::UInt64 val);
/// Returns the offset of the central directory from beginning of first disk
void setHeaderOffset(std::streamoff val);
/// Sets the offset of the header in relation to the begin of this disk
void setTotalNumberOfDisks(Poco::UInt32 val);
/// Sets the offset of the central directory from beginning of first disk
std::string createHeader() const;
/// Creates a header
private:
void parse(std::istream& inp, bool assumeHeaderRead);
void setRequiredVersion(int major, int minor);
private:
enum
{
HEADER_POS = 0,
RECORDSIZE_POS = HEADER_POS + ZipCommon::HEADER_SIZE,
RECORDSIZE_SIZE = 8,
VERSIONMADEBY_POS = RECORDSIZE_POS + RECORDSIZE_SIZE,
VERSIONMADEBY_SIZE = 2,
VERSION_NEEDED_POS = VERSIONMADEBY_POS + VERSIONMADEBY_SIZE,
VERSION_NEEDED_SIZE = 2,
NUMBEROFTHISDISK_POS = VERSION_NEEDED_POS + VERSION_NEEDED_SIZE,
NUMBEROFTHISDISK_SIZE = 4,
NUMBEROFCENTRALDIRDISK_POS = NUMBEROFTHISDISK_POS + NUMBEROFTHISDISK_SIZE,
NUMBEROFCENTRALDIRDISK_SIZE = 4,
NUMENTRIESTHISDISK_POS = NUMBEROFCENTRALDIRDISK_POS + NUMBEROFCENTRALDIRDISK_SIZE,
NUMENTRIESTHISDISK_SIZE = 8,
TOTALNUMENTRIES_POS = NUMENTRIESTHISDISK_POS + NUMENTRIESTHISDISK_SIZE,
TOTALNUMENTRIES_SIZE = 8,
CENTRALDIRSIZE_POS = TOTALNUMENTRIES_POS + TOTALNUMENTRIES_SIZE,
CENTRALDIRSIZE_SIZE = 8,
CENTRALDIRSTARTOFFSET_POS = CENTRALDIRSIZE_POS + CENTRALDIRSIZE_SIZE,
CENTRALDIRSTARTOFFSET_SIZE = 8,
FULL_HEADER_SIZE = 56,
LOCATOR_HEADER_POS = 0,
NUMBEROFENDOFCENTRALDIRDISK_POS = LOCATOR_HEADER_POS + ZipCommon::HEADER_SIZE,
NUMBEROFENDOFCENTRALDIRDISK_SIZE = 4,
ENDOFCENTRALDIROFFSET_POS = NUMBEROFENDOFCENTRALDIRDISK_POS + NUMBEROFENDOFCENTRALDIRDISK_SIZE,
ENDOFCENTRALDIROFFSET_SIZE = 8,
TOTALNUMBEROFENDDISKS_POS = ENDOFCENTRALDIROFFSET_POS + ENDOFCENTRALDIROFFSET_SIZE,
TOTALNUMBEROFENDDISKS_SIZE = 4,
FULL_LOCATOR_SIZE = 20
};
char _rawInfo[FULL_HEADER_SIZE];
std::string _extraField;
char _locInfo[FULL_LOCATOR_SIZE];
std::streamoff _startPos;
};
//
// inlines
//
inline Poco::UInt16 ZipArchiveInfo::getDiskNumber() const
{
return ZipUtil::get16BitValue(_rawInfo, NUMBEROFTHISDISK_POS);
@ -181,11 +301,105 @@ inline void ZipArchiveInfo::setCentralDirectorySize(Poco::UInt32 val)
}
inline void ZipArchiveInfo::setHeaderOffset(Poco::UInt32 val)
inline void ZipArchiveInfo::setCentralDirectoryOffset(Poco::UInt32 val)
{
ZipUtil::set32BitValue(val, _rawInfo, CENTRALDIRSTARTOFFSET_POS);
}
inline void ZipArchiveInfo::setHeaderOffset(std::streamoff val)
{
_startPos = val;
}
inline Poco::UInt32 ZipArchiveInfo64::getDiskNumber() const
{
return ZipUtil::get32BitValue(_rawInfo, NUMBEROFTHISDISK_POS);
}
inline Poco::UInt32 ZipArchiveInfo64::getFirstDiskForDirectoryHeader() const
{
return ZipUtil::get32BitValue(_rawInfo, NUMBEROFCENTRALDIRDISK_POS);
}
inline Poco::UInt64 ZipArchiveInfo64::getNumberOfEntries() const
{
return ZipUtil::get64BitValue(_rawInfo, NUMENTRIESTHISDISK_POS);
}
inline Poco::UInt64 ZipArchiveInfo64::getTotalNumberOfEntries() const
{
return ZipUtil::get64BitValue(_rawInfo, TOTALNUMENTRIES_POS);
}
inline Poco::UInt64 ZipArchiveInfo64::getCentralDirectorySize() const
{
return ZipUtil::get64BitValue(_rawInfo, CENTRALDIRSIZE_POS);
}
inline std::streamoff ZipArchiveInfo64::getCentralDirectoryOffset() const
{
return _startPos;
}
inline std::streamoff ZipArchiveInfo64::getHeaderOffset() const
{
return _startPos;
}
inline void ZipArchiveInfo64::setRequiredVersion(int major, int minor)
{
poco_assert (minor < 10);
poco_assert (major < 24);
Poco::UInt8 val = static_cast<unsigned char>(major)*10+static_cast<unsigned char>(minor);
_rawInfo[VERSIONMADEBY_POS] = static_cast<char>(val);
_rawInfo[VERSION_NEEDED_POS] = static_cast<char>(val);
}
inline void ZipArchiveInfo64::setNumberOfEntries(Poco::UInt64 val)
{
ZipUtil::set64BitValue(val, _rawInfo, NUMENTRIESTHISDISK_POS);
}
inline void ZipArchiveInfo64::setTotalNumberOfEntries(Poco::UInt64 val)
{
ZipUtil::set64BitValue(val, _rawInfo, TOTALNUMENTRIES_POS);
}
inline void ZipArchiveInfo64::setCentralDirectorySize(Poco::UInt64 val)
{
ZipUtil::set64BitValue(val, _rawInfo, CENTRALDIRSIZE_POS);
}
inline void ZipArchiveInfo64::setCentralDirectoryOffset(Poco::UInt64 val)
{
ZipUtil::set64BitValue(val, _rawInfo, CENTRALDIRSTARTOFFSET_POS);
}
inline void ZipArchiveInfo64::setHeaderOffset(std::streamoff val)
{
_startPos = val;
ZipUtil::set64BitValue(val, _locInfo, ENDOFCENTRALDIROFFSET_POS);
}
inline void ZipArchiveInfo64::setTotalNumberOfDisks(Poco::UInt32 val)
{
ZipUtil::set32BitValue(val, _locInfo, TOTALNUMBEROFENDDISKS_POS);
}
} } // namespace Poco::Zip

View File

@ -33,9 +33,13 @@ class Zip_API ZipCommon
public:
enum
{
HEADER_SIZE = 4
HEADER_SIZE = 4,
};
static const Poco::UInt16 ZIP64_EXTRA_ID = 0x1; // Extra data id tag for Zip64 data (in extension for ZipLocalFileHeader and ZipFileInfo)
static const Poco::UInt16 ZIP64_MAGIC_SHORT = 0xFFFF;
static const Poco::UInt32 ZIP64_MAGIC = 0xFFFFFFFF;
enum CompressionMethod
{
CM_STORE = 0,

View File

@ -80,6 +80,62 @@ private:
};
class Zip_API ZipDataInfo64
/// A ZipDataInfo64 stores a Zip data descriptor for a Zip64 file
{
public:
static const char HEADER[ZipCommon::HEADER_SIZE];
ZipDataInfo64();
/// Creates a header with all fields (except the header field) set to 0
ZipDataInfo64(std::istream& in, bool assumeHeaderRead);
/// Creates the ZipDataInfo64.
~ZipDataInfo64();
/// Destroys the ZipDataInfo64.
bool isValid() const;
Poco::UInt32 getCRC32() const;
void setCRC32(Poco::UInt32 crc);
Poco::UInt64 getCompressedSize() const;
void setCompressedSize(Poco::UInt64 size);
Poco::UInt64 getUncompressedSize() const;
void setUncompressedSize(Poco::UInt64 size);
static Poco::UInt32 getFullHeaderSize();
const char* getRawHeader() const;
private:
enum
{
HEADER_POS = 0,
CRC32_POS = HEADER_POS + ZipCommon::HEADER_SIZE,
CRC32_SIZE = 4,
COMPRESSED_POS = CRC32_POS + CRC32_SIZE,
COMPRESSED_SIZE = 8,
UNCOMPRESSED_POS = COMPRESSED_POS + COMPRESSED_SIZE,
UNCOMPRESSED_SIZE = 8,
FULLHEADER_SIZE = UNCOMPRESSED_POS + UNCOMPRESSED_SIZE
};
char _rawInfo[FULLHEADER_SIZE];
bool _valid;
};
//
// inlines
//
inline const char* ZipDataInfo::getRawHeader() const
{
return _rawInfo;
@ -134,6 +190,60 @@ inline Poco::UInt32 ZipDataInfo::getFullHeaderSize()
}
inline const char* ZipDataInfo64::getRawHeader() const
{
return _rawInfo;
}
inline bool ZipDataInfo64::isValid() const
{
return _valid;
}
inline Poco::UInt32 ZipDataInfo64::getCRC32() const
{
return ZipUtil::get32BitValue(_rawInfo, CRC32_POS);
}
inline void ZipDataInfo64::setCRC32(Poco::UInt32 crc)
{
return ZipUtil::set32BitValue(crc, _rawInfo, CRC32_POS);
}
inline Poco::UInt64 ZipDataInfo64::getCompressedSize() const
{
return ZipUtil::get64BitValue(_rawInfo, COMPRESSED_POS);
}
inline void ZipDataInfo64::setCompressedSize(Poco::UInt64 size)
{
return ZipUtil::set64BitValue(size, _rawInfo, COMPRESSED_POS);
}
inline Poco::UInt64 ZipDataInfo64::getUncompressedSize() const
{
return ZipUtil::get64BitValue(_rawInfo, UNCOMPRESSED_POS);
}
inline void ZipDataInfo64::setUncompressedSize(Poco::UInt64 size)
{
return ZipUtil::set64BitValue(size, _rawInfo, UNCOMPRESSED_POS);
}
inline Poco::UInt32 ZipDataInfo64::getFullHeaderSize()
{
return FULLHEADER_SIZE;
}
} } // namespace Poco::Zip

View File

@ -48,9 +48,6 @@ public:
~ZipFileInfo();
/// Destroys the ZipFileInfo.
Poco::UInt32 getRelativeOffsetOfLocalHeader() const;
/// Where on the disk starts the localheader. Combined with the disk number gives the exact location of the header
ZipCommon::CompressionMethod getCompressionMethod() const;
bool isEncrypted() const;
@ -62,9 +59,12 @@ public:
Poco::UInt32 getHeaderSize() const;
/// Returns the total size of the header including filename + other additional fields
Poco::UInt32 getCompressedSize() const;
Poco::UInt64 getCompressedSize() const;
Poco::UInt32 getUncompressedSize() const;
Poco::UInt64 getUncompressedSize() const;
Poco::UInt64 getOffset() const;
/// Where on the disk starts the localheader. Combined with the disk number gives the exact location of the header
const std::string& getFileName() const;
@ -94,14 +94,19 @@ public:
std::string createHeader() const;
void setOffset(Poco::UInt32 val);
void setOffset(Poco::UInt64 val);
bool needsZip64() const;
void setZip64Data();
private:
void setCRC(Poco::UInt32 val);
void setCompressedSize(Poco::UInt32 val);
void setCompressedSize(Poco::UInt64 val);
void setUncompressedSize(Poco::UInt32 val);
void setUncompressedSize(Poco::UInt64 val);
void setCompressionMethod(ZipCommon::CompressionMethod cm);
@ -131,6 +136,8 @@ private:
Poco::UInt32 getUncompressedSizeFromHeader() const;
Poco::UInt32 getOffsetFromHeader() const;
Poco::UInt16 getFileNameLength() const;
Poco::UInt16 getExtraFieldLength() const;
@ -177,7 +184,17 @@ private:
EXTERNALFILE_ATTR_SIZE = 4,
RELATIVEOFFSETLOCALHEADER_POS = EXTERNALFILE_ATTR_POS + EXTERNALFILE_ATTR_SIZE,
RELATIVEOFFSETLOCALHEADER_SIZE = 4,
FULLHEADER_SIZE = 46
FULLHEADER_SIZE = 46,
EXTRA_DATA_TAG_SIZE = 2,
EXTRA_DATA_TAG_POS = 0,
EXTRA_DATA_SIZE_SIZE = 2,
EXTRA_DATA_SIZE_POS = EXTRA_DATA_TAG_POS + EXTRA_DATA_TAG_SIZE,
EXTRA_DATA_POS = EXTRA_DATA_SIZE_POS + EXTRA_DATA_SIZE_SIZE,
EXTRA_DATA_UNCOMPRESSED_SIZE_SIZE = 8,
EXTRA_DATA_COMPRESSED_SIZE_SIZE = 8,
EXTRA_DATA_OFFSET_SIZE = 8,
FULLEXTRA_DATA_SIZE = 28
};
enum
@ -188,8 +205,9 @@ private:
char _rawInfo[FULLHEADER_SIZE];
Poco::UInt32 _crc32;
Poco::UInt32 _compressedSize;
Poco::UInt32 _uncompressedSize;
Poco::UInt64 _compressedSize;
Poco::UInt64 _uncompressedSize;
Poco::UInt64 _localHeaderOffset;
std::string _fileName;
Poco::DateTime _lastModifiedAt;
std::string _extraField;
@ -197,11 +215,6 @@ private:
};
inline Poco::UInt32 ZipFileInfo::getRelativeOffsetOfLocalHeader() const
{
return ZipUtil::get32BitValue(_rawInfo, RELATIVEOFFSETLOCALHEADER_POS);
}
inline Poco::UInt32 ZipFileInfo::getCRCFromHeader() const
{
@ -220,6 +233,11 @@ inline Poco::UInt32 ZipFileInfo::getUncompressedSizeFromHeader() const
return ZipUtil::get32BitValue(_rawInfo, UNCOMPRESSED_SIZE_POS);
}
inline Poco::UInt32 ZipFileInfo::getOffsetFromHeader() const
{
return ZipUtil::get32BitValue(_rawInfo, RELATIVEOFFSETLOCALHEADER_POS);
}
inline void ZipFileInfo::parseDateTime()
{
@ -246,19 +264,25 @@ inline const Poco::DateTime& ZipFileInfo::lastModifiedAt() const
}
inline Poco::UInt64 ZipFileInfo::getOffset() const
{
return _localHeaderOffset;
}
inline Poco::UInt32 ZipFileInfo::getCRC() const
{
return _crc32;
}
inline Poco::UInt32 ZipFileInfo::getCompressedSize() const
inline Poco::UInt64 ZipFileInfo::getCompressedSize() const
{
return _compressedSize;
}
inline Poco::UInt32 ZipFileInfo::getUncompressedSize() const
inline Poco::UInt64 ZipFileInfo::getUncompressedSize() const
{
return _uncompressedSize;
}
@ -363,6 +387,39 @@ inline Poco::UInt32 ZipFileInfo::getHeaderSize() const
}
inline bool ZipFileInfo::needsZip64() const
{
return _localHeaderOffset >= ZipCommon::ZIP64_MAGIC || _compressedSize >= ZipCommon::ZIP64_MAGIC || _uncompressedSize >= ZipCommon::ZIP64_MAGIC;
}
inline void ZipFileInfo::setZip64Data()
{
if (needsZip64())
{
setRequiredVersion(4, 5);
char data[FULLEXTRA_DATA_SIZE];
ZipUtil::set16BitValue(ZipCommon::ZIP64_EXTRA_ID, data, EXTRA_DATA_TAG_POS);
Poco::UInt16 pos = EXTRA_DATA_POS;
if (_uncompressedSize >= ZipCommon::ZIP64_MAGIC)
{
ZipUtil::set64BitValue(_uncompressedSize, data, pos); pos += 8;
}
if (_compressedSize >= ZipCommon::ZIP64_MAGIC)
{
ZipUtil::set64BitValue(_compressedSize, data, pos); pos += 8;
}
if (_localHeaderOffset >= ZipCommon::ZIP64_MAGIC)
{
ZipUtil::set64BitValue(_localHeaderOffset, data, pos); pos += 8;
}
ZipUtil::set16BitValue(pos - EXTRA_DATA_POS, data, EXTRA_DATA_SIZE_POS);
_extraField = std::string(data, pos);
ZipUtil::set16BitValue(pos, _rawInfo, EXTRAFIELD_LENGTH_POS);
}
}
inline void ZipFileInfo::setCRC(Poco::UInt32 val)
{
_crc32 = val;
@ -370,23 +427,24 @@ inline void ZipFileInfo::setCRC(Poco::UInt32 val)
}
inline void ZipFileInfo::setOffset(Poco::UInt32 val)
inline void ZipFileInfo::setOffset(Poco::UInt64 val)
{
ZipUtil::set32BitValue(val, _rawInfo, RELATIVEOFFSETLOCALHEADER_POS);
_localHeaderOffset = val;
ZipUtil::set32BitValue(val >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(val), _rawInfo, RELATIVEOFFSETLOCALHEADER_POS);
}
inline void ZipFileInfo::setCompressedSize(Poco::UInt32 val)
inline void ZipFileInfo::setCompressedSize(Poco::UInt64 val)
{
_compressedSize = val;
ZipUtil::set32BitValue(val, _rawInfo, COMPRESSED_SIZE_POS);
ZipUtil::set32BitValue(val >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(val), _rawInfo, COMPRESSED_SIZE_POS);
}
inline void ZipFileInfo::setUncompressedSize(Poco::UInt32 val)
inline void ZipFileInfo::setUncompressedSize(Poco::UInt64 val)
{
_uncompressedSize = val;
ZipUtil::set32BitValue(val, _rawInfo, UNCOMPRESSED_SIZE_POS);
ZipUtil::set32BitValue(val >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(val), _rawInfo, UNCOMPRESSED_SIZE_POS);
}

View File

@ -41,9 +41,10 @@ class Zip_API ZipLocalFileHeader
public:
static const char HEADER[ZipCommon::HEADER_SIZE];
ZipLocalFileHeader(const Poco::Path& fileName, const Poco::DateTime& lastModifiedAt, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl);
ZipLocalFileHeader(const Poco::Path& fileName, const Poco::DateTime& lastModifiedAt, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl, bool forceZip64 = false);
/// Creates a zip file header from an absoluteFile. fileName is the name of the file in the zip, outputIsSeekable determines if we write
/// CRC and file sizes to the LocalFileHeader or after data compression into a ZipDataInfo
/// If forceZip64 is set true then the file header is allocated with zip64 extension.
ZipLocalFileHeader(std::istream& inp, bool assumeHeaderRead, ParseCallback& callback);
/// Creates the ZipLocalFileHeader by parsing the input stream.
@ -90,15 +91,15 @@ public:
Poco::UInt32 getCRC() const;
Poco::UInt32 getCompressedSize() const;
Poco::UInt64 getCompressedSize() const;
Poco::UInt32 getUncompressedSize() const;
Poco::UInt64 getUncompressedSize() const;
void setCRC(Poco::UInt32 val);
void setCompressedSize(Poco::UInt32 val);
void setCompressedSize(Poco::UInt64 val);
void setUncompressedSize(Poco::UInt32 val);
void setUncompressedSize(Poco::UInt64 val);
const std::string& getFileName() const;
@ -118,6 +119,10 @@ public:
void setFileName(const std::string& fileName, bool isDirectory);
bool needsZip64() const;
void setZip64Data();
std::string createHeader() const;
/// Creates a header
@ -170,17 +175,27 @@ private:
LASTMODEFILEDATE_POS = LASTMODEFILETIME_POS + LASTMODEFILETIME_SIZE,
CRC32_SIZE = 4,
CRC32_POS = LASTMODEFILEDATE_POS + LASTMODEFILEDATE_SIZE,
COMPRESSEDSIZE_SIZE = 4,
COMPRESSEDSIZE_POS = CRC32_POS + CRC32_SIZE,
UNCOMPRESSEDSIZE_SIZE = 4,
UNCOMPRESSEDSIZE_POS = COMPRESSEDSIZE_POS + COMPRESSEDSIZE_SIZE,
FILELENGTH_SIZE = 2,
FILELENGTH_POS = UNCOMPRESSEDSIZE_POS + UNCOMPRESSEDSIZE_SIZE,
EXTRAFIELD_LENGTH = 2,
EXTRAFIELD_POS = FILELENGTH_POS + FILELENGTH_SIZE,
FULLHEADER_SIZE = 30
COMPRESSED_SIZE_SIZE = 4,
COMPRESSED_SIZE_POS = CRC32_POS + CRC32_SIZE,
UNCOMPRESSED_SIZE_SIZE = 4,
UNCOMPRESSED_SIZE_POS = COMPRESSED_SIZE_POS + COMPRESSED_SIZE_SIZE,
FILE_LENGTH_SIZE = 2,
FILE_LENGTH_POS = UNCOMPRESSED_SIZE_POS + UNCOMPRESSED_SIZE_SIZE,
EXTRA_FIELD_LENGTH = 2,
EXTRA_FIELD_POS = FILE_LENGTH_POS + FILE_LENGTH_SIZE,
FULLHEADER_SIZE = 30,
EXTRA_DATA_TAG_SIZE = 2,
EXTRA_DATA_TAG_POS = 0,
EXTRA_DATA_SIZE_SIZE = 2,
EXTRA_DATA_SIZE_POS = EXTRA_DATA_TAG_POS + EXTRA_DATA_TAG_SIZE,
EXTRA_DATA_POS = EXTRA_DATA_SIZE_POS + EXTRA_DATA_SIZE_SIZE,
EXTRA_DATA_UNCOMPRESSED_SIZE_SIZE = 8,
EXTRA_DATA_COMPRESSED_SIZE_SIZE = 8,
FULLEXTRA_DATA_SIZE = 20
};
bool _forceZip64;
char _rawHeader[FULLHEADER_SIZE];
std::streamoff _startPos;
std::streamoff _endPos;
@ -188,20 +203,20 @@ private:
Poco::DateTime _lastModifiedAt;
std::string _extraField;
Poco::UInt32 _crc32;
Poco::UInt32 _compressedSize;
Poco::UInt32 _uncompressedSize;
Poco::UInt64 _compressedSize;
Poco::UInt64 _uncompressedSize;
};
inline void ZipLocalFileHeader::setFileNameLength(Poco::UInt16 size)
{
ZipUtil::set16BitValue(size, _rawHeader, FILELENGTH_POS);
ZipUtil::set16BitValue(size, _rawHeader, FILE_LENGTH_POS);
}
inline void ZipLocalFileHeader::setExtraFieldSize(Poco::UInt16 size)
{
ZipUtil::set16BitValue(size, _rawHeader, EXTRAFIELD_POS);
ZipUtil::set16BitValue(size, _rawHeader, EXTRA_FIELD_POS);
}
@ -236,6 +251,28 @@ inline void ZipLocalFileHeader::getRequiredVersion(int& major, int& minor)
}
inline bool ZipLocalFileHeader::needsZip64() const
{
return _forceZip64 || _startPos >= ZipCommon::ZIP64_MAGIC || _compressedSize >= ZipCommon::ZIP64_MAGIC || _uncompressedSize >= ZipCommon::ZIP64_MAGIC;
}
inline void ZipLocalFileHeader::setZip64Data()
{
setRequiredVersion(4, 5);
char data[FULLEXTRA_DATA_SIZE];
ZipUtil::set16BitValue(ZipCommon::ZIP64_EXTRA_ID, data, EXTRA_DATA_TAG_POS);
Poco::UInt16 pos = EXTRA_DATA_POS;
ZipUtil::set64BitValue(_uncompressedSize, data, pos); pos += 8;
ZipUtil::set32BitValue(ZipCommon::ZIP64_MAGIC, _rawHeader, UNCOMPRESSED_SIZE_POS);
ZipUtil::set64BitValue(_compressedSize, data, pos); pos += 8;
ZipUtil::set32BitValue(ZipCommon::ZIP64_MAGIC, _rawHeader, COMPRESSED_SIZE_POS);
ZipUtil::set16BitValue(pos - EXTRA_DATA_POS, data, EXTRA_DATA_SIZE_POS);
_extraField = std::string(data, pos);
ZipUtil::set16BitValue(pos, _rawHeader, EXTRA_FIELD_POS);
}
inline void ZipLocalFileHeader::setRequiredVersion(int major, int minor)
{
poco_assert (minor < 10);
@ -245,13 +282,13 @@ inline void ZipLocalFileHeader::setRequiredVersion(int major, int minor)
inline Poco::UInt16 ZipLocalFileHeader::getFileNameLength() const
{
return ZipUtil::get16BitValue(_rawHeader, FILELENGTH_POS);
return ZipUtil::get16BitValue(_rawHeader, FILE_LENGTH_POS);
}
inline Poco::UInt16 ZipLocalFileHeader::getExtraFieldLength() const
{
return ZipUtil::get16BitValue(_rawHeader, EXTRAFIELD_POS);
return ZipUtil::get16BitValue(_rawHeader, EXTRA_FIELD_POS);
}
@ -360,13 +397,13 @@ inline Poco::UInt32 ZipLocalFileHeader::getCRC() const
}
inline Poco::UInt32 ZipLocalFileHeader::getCompressedSize() const
inline Poco::UInt64 ZipLocalFileHeader::getCompressedSize() const
{
return _compressedSize;
}
inline Poco::UInt32 ZipLocalFileHeader::getUncompressedSize() const
inline Poco::UInt64 ZipLocalFileHeader::getUncompressedSize() const
{
return _uncompressedSize;
}
@ -379,17 +416,17 @@ inline void ZipLocalFileHeader::setCRC(Poco::UInt32 val)
}
inline void ZipLocalFileHeader::setCompressedSize(Poco::UInt32 val)
inline void ZipLocalFileHeader::setCompressedSize(Poco::UInt64 val)
{
_compressedSize = val;
ZipUtil::set32BitValue(val, _rawHeader, COMPRESSEDSIZE_POS);
ZipUtil::set32BitValue(val >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(val), _rawHeader, COMPRESSED_SIZE_POS);
}
inline void ZipLocalFileHeader::setUncompressedSize(Poco::UInt32 val)
inline void ZipLocalFileHeader::setUncompressedSize(Poco::UInt64 val)
{
_uncompressedSize = val;
ZipUtil::set32BitValue(val, _rawHeader, UNCOMPRESSEDSIZE_POS);
ZipUtil::set32BitValue(val >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(val), _rawHeader, UNCOMPRESSED_SIZE_POS);
}
@ -401,13 +438,13 @@ inline Poco::UInt32 ZipLocalFileHeader::getCRCFromHeader() const
inline Poco::UInt32 ZipLocalFileHeader::getCompressedSizeFromHeader() const
{
return ZipUtil::get32BitValue(_rawHeader, COMPRESSEDSIZE_POS);
return ZipUtil::get32BitValue(_rawHeader, COMPRESSED_SIZE_POS);
}
inline Poco::UInt32 ZipLocalFileHeader::getUncompressedSizeFromHeader() const
{
return ZipUtil::get32BitValue(_rawHeader, UNCOMPRESSEDSIZE_POS);
return ZipUtil::get32BitValue(_rawHeader, UNCOMPRESSED_SIZE_POS);
}

View File

@ -50,7 +50,7 @@ public:
virtual ~ZipStreamBuf();
/// Destroys the ZipStreamBuf.
void close();
void close(Poco::UInt64& extraDataSize);
/// Informs a writing outputstream that writing is done for this stream
bool crcValid() const;
@ -79,7 +79,7 @@ private:
Poco::UInt32 _expectedCrc32;
bool _checkCRC;
/// Note: we do not check crc if we decompress a streaming zip file and the crc is stored in the directory header
Poco::UInt32 _bytesWritten;
Poco::UInt64 _bytesWritten;
ZipLocalFileHeader* _pHeader;
};
@ -140,7 +140,7 @@ public:
~ZipOutputStream();
/// Destroys the ZipOutputStream.
void close();
void close(Poco::UInt64& extraDataSize);
/// Must be called for ZipOutputStreams!
};

View File

@ -39,10 +39,14 @@ public:
static Poco::UInt32 get32BitValue(const char* pVal, const Poco::UInt32 pos);
static Poco::UInt64 get64BitValue(const char* pVal, const Poco::UInt32 pos);
static void set16BitValue(const Poco::UInt16 val, char* pVal, const Poco::UInt32 pos);
static void set32BitValue(const Poco::UInt32 val, char* pVal, const Poco::UInt32 pos);
static void set64BitValue(const Poco::UInt64 val, char* pVal, const Poco::UInt32 pos);
static Poco::DateTime parseDateTime(const char* pVal, const Poco::UInt32 timePos, const Poco::UInt32 datePos);
static void setDateTime(const Poco::DateTime& dt, char* pVal, const Poco::UInt32 timePos, const Poco::UInt32 datePos);
@ -78,6 +82,14 @@ inline Poco::UInt32 ZipUtil::get32BitValue(const char* pVal, const Poco::UInt32
}
inline Poco::UInt64 ZipUtil::get64BitValue(const char* pVal, const Poco::UInt32 pos)
{
Poco::UInt64 val = ZipUtil::get32BitValue(pVal, pos+4);
val = (val << 32) | ZipUtil::get32BitValue(pVal, pos);
return val;
}
inline void ZipUtil::set16BitValue(const Poco::UInt16 val, char* pVal, const Poco::UInt32 pos)
{
pVal[pos] = static_cast<char>(val);
@ -94,6 +106,19 @@ inline void ZipUtil::set32BitValue(const Poco::UInt32 val, char* pVal, const Poc
}
inline void ZipUtil::set64BitValue(const Poco::UInt64 val, char* pVal, const Poco::UInt32 pos)
{
pVal[pos] = static_cast<char>(val);
pVal[pos+1] = static_cast<char>(val>>8);
pVal[pos+2] = static_cast<char>(val>>16);
pVal[pos+3] = static_cast<char>(val>>24);
pVal[pos+4] = static_cast<char>(val>>32);
pVal[pos+5] = static_cast<char>(val>>40);
pVal[pos+6] = static_cast<char>(val>>48);
pVal[pos+7] = static_cast<char>(val>>56);
}
} } // namespace Poco::Zip

View File

@ -30,9 +30,10 @@ namespace Poco {
namespace Zip {
Compress::Compress(std::ostream& out, bool seekableOut):
Compress::Compress(std::ostream& out, bool seekableOut, bool forceZip64):
_out(out),
_seekableOut(seekableOut),
_forceZip64(forceZip64),
_files(),
_infos(),
_dirs(),
@ -63,26 +64,24 @@ void Compress::addEntry(std::istream& in, const Poco::DateTime& lastModifiedAt,
std::string fn = ZipUtil::validZipEntryFileName(fileName);
if (_files.size() >= 65535)
throw ZipException("Maximum number of entries for a ZIP file reached: 65535");
if (!in.good())
throw ZipException("Invalid input stream");
std::streamoff localHeaderOffset = _offset;
ZipLocalFileHeader hdr(fileName, lastModifiedAt, cm, cl);
ZipLocalFileHeader hdr(fileName, lastModifiedAt, cm, cl, _forceZip64);
hdr.setStartPos(localHeaderOffset);
ZipOutputStream zipOut(_out, hdr, _seekableOut);
Poco::StreamCopier::copyStream(in, zipOut);
zipOut.close();
hdr.setStartPos(localHeaderOffset); // reset again now that compressed Size is known
Poco::UInt64 extraDataSize;
zipOut.close(extraDataSize);
_offset = hdr.getEndPos();
if (hdr.searchCRCAndSizesAfterData())
_offset += ZipDataInfo::getFullHeaderSize();
_offset += extraDataSize;
_files.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), hdr));
poco_assert (_out);
ZipFileInfo nfo(hdr);
nfo.setOffset(localHeaderOffset);
nfo.setZip64Data();
_infos.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), nfo));
EDone.notify(this, hdr);
}
@ -94,8 +93,6 @@ void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const P
//bypass the header of the input stream and point to the first byte of the data payload
in.seekg(h.getDataStartPos(), std::ios_base::beg);
if (_files.size() >= 65535)
throw ZipException("Maximum number of entries for a ZIP file reached: 65535");
if (!in.good())
throw ZipException("Invalid input stream");
@ -103,16 +100,18 @@ void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const P
ZipLocalFileHeader hdr(h);
hdr.setFileName(fn, h.isDirectory());
hdr.setStartPos(localHeaderOffset);
if(hdr.needsZip64())
hdr.setZip64Data();
//bypass zipoutputstream
//write the header directly
std::string header = hdr.createHeader();
_out.write(header.c_str(), static_cast<std::streamsize>(header.size()));
// now fwd the payload to _out in chunks of size CHUNKSIZE
Poco::UInt32 totalSize = hdr.getCompressedSize();
Poco::UInt64 totalSize = hdr.getCompressedSize();
if (totalSize > 0)
{
Poco::Buffer<char> buffer(COMPRESS_CHUNK_SIZE);
Poco::UInt32 remaining = totalSize;
Poco::UInt64 remaining = totalSize;
while(remaining > 0)
{
if (remaining > COMPRESS_CHUNK_SIZE)
@ -133,20 +132,39 @@ void Compress::addFileRaw(std::istream& in, const ZipLocalFileHeader& h, const P
}
}
}
hdr.setStartPos(localHeaderOffset); // This resets EndPos now that compressed Size is known
_offset = hdr.getEndPos();
//write optional block afterwards
if (hdr.searchCRCAndSizesAfterData())
{
if (hdr.needsZip64())
{
ZipDataInfo64 info(in, false);
_out.write(info.getRawHeader(), static_cast<std::streamsize>(info.getFullHeaderSize()));
_offset += ZipDataInfo::getFullHeaderSize();
}
else
{
ZipDataInfo info(in, false);
_out.write(info.getRawHeader(), static_cast<std::streamsize>(info.getFullHeaderSize()));
}
hdr.setStartPos(localHeaderOffset); // reset again now that compressed Size is known
_offset = hdr.getEndPos();
if (hdr.searchCRCAndSizesAfterData())
_offset += ZipDataInfo::getFullHeaderSize();
}
}
else
{
if(hdr.hasExtraField()) // Update sizes in header extension.
hdr.setZip64Data();
_out.seekp(hdr.getStartPos(), std::ios_base::beg);
std::string header = hdr.createHeader();
_out.write(header.c_str(), static_cast<std::streamsize>(header.size()));
_out.seekp(0, std::ios_base::end);
}
_files.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), hdr));
poco_assert (_out);
ZipFileInfo nfo(hdr);
nfo.setOffset(localHeaderOffset);
nfo.setZip64Data();
_infos.insert(std::make_pair(fileName.toString(Poco::Path::PATH_UNIX), nfo));
EDone.notify(this, hdr);
}
@ -186,8 +204,6 @@ void Compress::addDirectory(const Poco::Path& entryName, const Poco::DateTime& l
std::string fileStr = entryName.toString(Poco::Path::PATH_UNIX);
if (_files.find(fileStr) != _files.end())
return; // ignore duplicate add
if (_files.size() >= 65535)
throw ZipException("Maximum number of entries for a ZIP file reached: 65535");
if (fileStr == "/")
throw ZipException("Illegal entry name /");
if (fileStr.empty())
@ -206,15 +222,17 @@ void Compress::addDirectory(const Poco::Path& entryName, const Poco::DateTime& l
ZipLocalFileHeader hdr(entryName, lastModifiedAt, cm, cl);
hdr.setStartPos(localHeaderOffset);
ZipOutputStream zipOut(_out, hdr, _seekableOut);
zipOut.close();
Poco::UInt64 extraDataSize;
zipOut.close(extraDataSize);
hdr.setStartPos(localHeaderOffset); // reset again now that compressed Size is known
_offset = hdr.getEndPos();
if (hdr.searchCRCAndSizesAfterData())
_offset += ZipDataInfo::getFullHeaderSize();
_offset += extraDataSize;
_files.insert(std::make_pair(entryName.toString(Poco::Path::PATH_UNIX), hdr));
poco_assert (_out);
ZipFileInfo nfo(hdr);
nfo.setOffset(localHeaderOffset);
nfo.setZip64Data();
_infos.insert(std::make_pair(entryName.toString(Poco::Path::PATH_UNIX), nfo));
EDone.notify(this, hdr);
}
@ -274,34 +292,58 @@ void Compress::addRecursive(const Poco::Path& entry, ZipCommon::CompressionMetho
ZipArchive Compress::close()
{
if (!_dirs.empty())
return ZipArchive(_files, _infos, _dirs);
if (!_dirs.empty() || ! _dirs64.empty())
return ZipArchive(_files, _infos, _dirs, _dirs64);
poco_assert (_infos.size() == _files.size());
poco_assert (_files.size() < 65536);
Poco::UInt32 centralDirStart = _offset;
Poco::UInt32 centralDirSize = 0;
Poco::UInt64 centralDirSize64 = 0;
Poco::UInt64 centralDirStart64 = _offset;
// write all infos
ZipArchive::FileInfos::const_iterator it = _infos.begin();
ZipArchive::FileInfos::const_iterator itEnd = _infos.end();
bool needZip64 = _forceZip64;
needZip64 = needZip64 || _files.size() >= ZipCommon::ZIP64_MAGIC_SHORT || centralDirStart64 >= ZipCommon::ZIP64_MAGIC;
for (; it != itEnd; ++it)
{
const ZipFileInfo& nfo = it->second;
needZip64 = needZip64 || nfo.needsZip64();
std::string info(nfo.createHeader());
_out.write(info.c_str(), static_cast<std::streamsize>(info.size()));
Poco::UInt32 entrySize = static_cast<Poco::UInt32>(info.size());
centralDirSize += entrySize;
centralDirSize64 += entrySize;
_offset += entrySize;
}
poco_assert (_out);
Poco::UInt64 numEntries64 = _infos.size();
needZip64 = needZip64 || _offset >= ZipCommon::ZIP64_MAGIC;
if(needZip64)
{
ZipArchiveInfo64 central;
central.setCentralDirectorySize(centralDirSize64);
central.setCentralDirectoryOffset(centralDirStart64);
central.setNumberOfEntries(numEntries64);
central.setTotalNumberOfEntries(numEntries64);
central.setHeaderOffset(_offset);
central.setTotalNumberOfDisks(1);
std::string centr(central.createHeader());
_out.write(centr.c_str(), static_cast<std::streamsize>(centr.size()));
_out.flush();
_offset += centr.size();
_dirs64.insert(std::make_pair(0, central));
}
Poco::UInt16 numEntries = static_cast<Poco::UInt16>(_infos.size());
Poco::UInt16 numEntries = numEntries64 >= ZipCommon::ZIP64_MAGIC_SHORT ? ZipCommon::ZIP64_MAGIC_SHORT : static_cast<Poco::UInt16>(numEntries64);
Poco::UInt32 centralDirStart = centralDirStart64 >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(centralDirStart64);
Poco::UInt32 centralDirSize = centralDirSize64 >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(centralDirSize64);
Poco::UInt32 offset = _offset >= ZipCommon::ZIP64_MAGIC ? ZipCommon::ZIP64_MAGIC : static_cast<Poco::UInt32>(_offset);
ZipArchiveInfo central;
central.setCentralDirectorySize(centralDirSize);
central.setCentralDirectoryOffset(centralDirStart);
central.setNumberOfEntries(numEntries);
central.setTotalNumberOfEntries(numEntries);
central.setHeaderOffset(centralDirStart);
central.setHeaderOffset(offset);
if (!_comment.empty() && _comment.size() <= 65535)
{
central.setZipComment(_comment);
@ -309,8 +351,9 @@ ZipArchive Compress::close()
std::string centr(central.createHeader());
_out.write(centr.c_str(), static_cast<std::streamsize>(centr.size()));
_out.flush();
_offset += centr.size();
_dirs.insert(std::make_pair(0, central));
return ZipArchive(_files, _infos, _dirs);
return ZipArchive(_files, _infos, _dirs, _dirs64);
}

View File

@ -27,7 +27,8 @@ namespace Zip {
ZipArchive::ZipArchive(std::istream& in):
_entries(),
_infos(),
_disks()
_disks(),
_disks64()
{
poco_assert_dbg (in);
SkipCallback skip;
@ -35,10 +36,11 @@ ZipArchive::ZipArchive(std::istream& in):
}
ZipArchive::ZipArchive(const FileHeaders& entries, const FileInfos& infos, const DirectoryInfos& dirs):
ZipArchive::ZipArchive(const FileHeaders& entries, const FileInfos& infos, const DirectoryInfos& dirs, const DirectoryInfos64& dirs64):
_entries(entries),
_infos(infos),
_disks(dirs)
_disks(dirs),
_disks64(dirs64)
{
}
@ -46,7 +48,8 @@ ZipArchive::ZipArchive(const FileHeaders& entries, const FileInfos& infos, const
ZipArchive::ZipArchive(std::istream& in, ParseCallback& pc):
_entries(),
_infos(),
_disks()
_disks(),
_disks64()
{
poco_assert_dbg (in);
parse(in, pc);
@ -78,7 +81,7 @@ void ZipArchive::parse(std::istream& in, ParseCallback& pc)
FileHeaders::iterator it = _entries.find(info.getFileName());
if (it != _entries.end())
{
it->second.setStartPos(info.getRelativeOffsetOfLocalHeader());
it->second.setStartPos(info.getOffset());
}
poco_assert (_infos.insert(std::make_pair(info.getFileName(), info)).second);
}
@ -87,9 +90,14 @@ void ZipArchive::parse(std::istream& in, ParseCallback& pc)
ZipArchiveInfo nfo(in, true);
poco_assert (_disks.insert(std::make_pair(nfo.getDiskNumber(), nfo)).second);
}
else if (std::memcmp(header, ZipArchiveInfo64::HEADER, ZipCommon::HEADER_SIZE) == 0)
{
ZipArchiveInfo64 nfo(in, true);
poco_assert (_disks64.insert(std::make_pair(nfo.getDiskNumber(), nfo)).second);
}
else
{
if (_disks.empty())
if (_disks.empty() && _disks64.empty())
throw Poco::IllegalStateException("Illegal header in zip file");
else
throw Poco::IllegalStateException("Garbage after directory header");

View File

@ -38,6 +38,7 @@ ZipArchiveInfo::ZipArchiveInfo(std::istream& in, bool assumeHeaderRead):
parse(in, assumeHeaderRead);
}
ZipArchiveInfo::ZipArchiveInfo():
_rawInfo(),
_startPos(0),
@ -98,4 +99,82 @@ void ZipArchiveInfo::setZipComment(const std::string& comment)
}
const char ZipArchiveInfo64::HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b', '\x06', '\x06'};
const char ZipArchiveInfo64::LOCATOR_HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b', '\x06', '\x07'};
ZipArchiveInfo64::ZipArchiveInfo64(std::istream& in, bool assumeHeaderRead):
_rawInfo(),
_startPos(in.tellg())
{
if (assumeHeaderRead)
_startPos -= ZipCommon::HEADER_SIZE;
parse(in, assumeHeaderRead);
}
ZipArchiveInfo64::ZipArchiveInfo64():
_rawInfo(),
_startPos(0)
{
std::memset(_rawInfo, 0, FULL_HEADER_SIZE);
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
ZipUtil::set64BitValue(FULL_HEADER_SIZE - (RECORDSIZE_POS + RECORDSIZE_SIZE), _rawInfo, RECORDSIZE_POS);
std::memset(_locInfo, 0, FULL_LOCATOR_SIZE);
std::memcpy(_locInfo, LOCATOR_HEADER, ZipCommon::HEADER_SIZE);
setRequiredVersion(4, 5);
}
ZipArchiveInfo64::~ZipArchiveInfo64()
{
}
void ZipArchiveInfo64::parse(std::istream& inp, bool assumeHeaderRead)
{
if (!assumeHeaderRead)
{
inp.read(_rawInfo, ZipCommon::HEADER_SIZE);
}
else
{
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
}
poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0);
std::memset(_rawInfo + ZipCommon::HEADER_SIZE, 0, FULL_HEADER_SIZE - ZipCommon::HEADER_SIZE);
// read the rest of the header
Poco::UInt64 offset = RECORDSIZE_POS;
inp.read(_rawInfo + ZipCommon::HEADER_SIZE, RECORDSIZE_SIZE);
offset += RECORDSIZE_SIZE;
Poco::UInt64 len = ZipUtil::get64BitValue(_rawInfo, RECORDSIZE_POS);
if (len <= FULL_HEADER_SIZE - offset)
{
inp.read(_rawInfo + offset, len);
ZipUtil::set64BitValue(FULL_HEADER_SIZE - offset, _rawInfo, RECORDSIZE_POS);
}
else
{
inp.read(_rawInfo + offset, FULL_HEADER_SIZE - offset);
len -= (FULL_HEADER_SIZE - offset);
Poco::Buffer<char> xtra(len);
inp.read(xtra.begin(), len);
_extraField = std::string(xtra.begin(), len);
ZipUtil::set64BitValue(FULL_HEADER_SIZE + len - offset, _rawInfo, RECORDSIZE_POS);
}
inp.read(_locInfo, FULL_LOCATOR_SIZE);
poco_assert (std::memcmp(_locInfo, LOCATOR_HEADER, ZipCommon::HEADER_SIZE) == 0);
}
std::string ZipArchiveInfo64::createHeader() const
{
std::string result(_rawInfo, FULL_HEADER_SIZE);
result.append(_extraField);
result.append(_locInfo, FULL_LOCATOR_SIZE);
return result;
}
} } // namespace Poco::Zip

View File

@ -56,4 +56,38 @@ ZipDataInfo::~ZipDataInfo()
}
const char ZipDataInfo64::HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b', '\x07', '\x08'};
ZipDataInfo64::ZipDataInfo64():
_rawInfo(),
_valid(true)
{
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
std::memset(_rawInfo+ZipCommon::HEADER_SIZE, 0, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
_valid = true;
}
ZipDataInfo64::ZipDataInfo64(std::istream& in, bool assumeHeaderRead):
_rawInfo(),
_valid(false)
{
if (assumeHeaderRead)
std::memcpy(_rawInfo, HEADER, ZipCommon::HEADER_SIZE);
else
in.read(_rawInfo, ZipCommon::HEADER_SIZE);
poco_assert (std::memcmp(_rawInfo, HEADER, ZipCommon::HEADER_SIZE) == 0);
// now copy the rest of the header
in.read(_rawInfo+ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
_valid = (!in.eof() && in.good());
}
ZipDataInfo64::~ZipDataInfo64()
{
}
} } // namespace Poco::Zip

View File

@ -33,6 +33,7 @@ ZipFileInfo::ZipFileInfo(const ZipLocalFileHeader& header):
_crc32(0),
_compressedSize(0),
_uncompressedSize(0),
_localHeaderOffset(0),
_fileName(),
_lastModifiedAt(),
_extraField()
@ -52,6 +53,8 @@ ZipFileInfo::ZipFileInfo(const ZipLocalFileHeader& header):
if (getHostSystem() == ZipCommon::HS_UNIX)
setUnixAttributes();
_rawInfo[GENERAL_PURPOSE_POS+1] |= 0x08; // Set "language encoding flag" to indicate that filenames and paths are in UTF-8.
}
@ -60,6 +63,7 @@ ZipFileInfo::ZipFileInfo(std::istream& in, bool assumeHeaderRead):
_crc32(0),
_compressedSize(0),
_uncompressedSize(0),
_localHeaderOffset(0),
_fileName(),
_lastModifiedAt(),
_extraField()
@ -102,6 +106,25 @@ void ZipFileInfo::parse(std::istream& inp, bool assumeHeaderRead)
Poco::Buffer<char> xtra(len);
inp.read(xtra.begin(), len);
_extraField = std::string(xtra.begin(), len);
char* ptr = xtra.begin();
while(ptr <= xtra.begin() + len - 4) {
Poco::UInt16 id = ZipUtil::get16BitValue(ptr, 0); ptr +=2;
Poco::UInt16 size = ZipUtil::get16BitValue(ptr, 0); ptr += 2;
if(id == ZipCommon::ZIP64_EXTRA_ID) {
poco_assert(size >= 8);
if(getUncompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC) {
setUncompressedSize(ZipUtil::get64BitValue(ptr, 0)); size -= 8; ptr += 8;
}
if(size >= 8 && getCompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC) {
setCompressedSize(ZipUtil::get64BitValue(ptr, 0)); size -= 8; ptr += 8;
}
if(size >= 8 && getOffsetFromHeader() == ZipCommon::ZIP64_MAGIC) {
setOffset(ZipUtil::get64BitValue(ptr, 0)); size -= 8; ptr += 8;
}
} else {
ptr += size;
}
}
}
len = getFileCommentLength();
if (len > 0)

View File

@ -33,7 +33,9 @@ const char ZipLocalFileHeader::HEADER[ZipCommon::HEADER_SIZE] = {'\x50', '\x4b',
ZipLocalFileHeader::ZipLocalFileHeader(const Poco::Path& fileName,
const Poco::DateTime& lastModifiedAt,
ZipCommon::CompressionMethod cm,
ZipCommon::CompressionLevel cl):
ZipCommon::CompressionLevel cl,
bool forceZip64):
_forceZip64(forceZip64),
_rawHeader(),
_startPos(-1),
_endPos(-1),
@ -66,6 +68,7 @@ ZipLocalFileHeader::ZipLocalFileHeader(const Poco::Path& fileName,
ZipLocalFileHeader::ZipLocalFileHeader(std::istream& inp, bool assumeHeaderRead, ParseCallback& callback):
_forceZip64(false),
_rawHeader(),
_startPos(inp.tellg()),
_endPos(-1),
@ -76,7 +79,7 @@ ZipLocalFileHeader::ZipLocalFileHeader(std::istream& inp, bool assumeHeaderRead,
_compressedSize(0),
_uncompressedSize(0)
{
poco_assert_dbg( (EXTRAFIELD_POS+EXTRAFIELD_LENGTH) == FULLHEADER_SIZE);
poco_assert_dbg( (EXTRA_FIELD_POS+EXTRA_FIELD_LENGTH) == FULLHEADER_SIZE);
if (assumeHeaderRead)
_startPos -= ZipCommon::HEADER_SIZE;
@ -89,11 +92,23 @@ ZipLocalFileHeader::ZipLocalFileHeader(std::istream& inp, bool assumeHeaderRead,
{
if (searchCRCAndSizesAfterData())
{
ZipDataInfo nfo(inp, false);
char header[ZipCommon::HEADER_SIZE]={'\x00', '\x00', '\x00', '\x00'};
inp.read(header, ZipCommon::HEADER_SIZE);
if (std::memcmp(header, ZipDataInfo64::HEADER, sizeof(header)) == 0)
{
ZipDataInfo64 nfo(inp, true);
setCRC(nfo.getCRC32());
setCompressedSize(nfo.getCompressedSize());
setUncompressedSize(nfo.getUncompressedSize());
}
else
{
ZipDataInfo nfo(inp, true);
setCRC(nfo.getCRC32());
setCompressedSize(nfo.getCompressedSize());
setUncompressedSize(nfo.getUncompressedSize());
}
}
}
else
{
@ -122,28 +137,52 @@ void ZipLocalFileHeader::parse(std::istream& inp, bool assumeHeaderRead)
poco_assert (std::memcmp(_rawHeader, HEADER, ZipCommon::HEADER_SIZE) == 0);
// read the rest of the header
inp.read(_rawHeader + ZipCommon::HEADER_SIZE, FULLHEADER_SIZE - ZipCommon::HEADER_SIZE);
if (!(_rawHeader[VERSION_POS + 1]>= ZipCommon::HS_FAT && _rawHeader[VERSION_POS + 1] < ZipCommon::HS_UNUSED))
throw Poco::DataFormatException("bad ZIP file header", "invalid version");
if (ZipUtil::get16BitValue(_rawHeader, COMPR_METHOD_POS) >= ZipCommon::CM_UNUSED)
throw Poco::DataFormatException("bad ZIP file header", "invalid compression method");
poco_assert (_rawHeader[VERSION_POS + 1]>= ZipCommon::HS_FAT && _rawHeader[VERSION_POS + 1] < ZipCommon::HS_UNUSED);
poco_assert (getMajorVersionNumber() <= 4); // Allow for Zip64 version 4.5
poco_assert (ZipUtil::get16BitValue(_rawHeader, COMPR_METHOD_POS) < ZipCommon::CM_UNUSED);
parseDateTime();
Poco::UInt16 len = getFileNameLength();
Poco::Buffer<char> buf(len);
inp.read(buf.begin(), len);
_fileName = std::string(buf.begin(), len);
if (hasExtraField())
{
len = getExtraFieldLength();
Poco::Buffer<char> xtra(len);
inp.read(xtra.begin(), len);
_extraField = std::string(xtra.begin(), len);
}
if (!searchCRCAndSizesAfterData())
{
_crc32 = getCRCFromHeader();
_compressedSize = getCompressedSizeFromHeader();
_uncompressedSize = getUncompressedSizeFromHeader();
}
if (hasExtraField())
{
len = getExtraFieldLength();
Poco::Buffer<char> xtra(len);
inp.read(xtra.begin(), len);
_extraField = std::string(xtra.begin(), len);
char* ptr = xtra.begin();
while (ptr <= xtra.begin() + len - 4)
{
Poco::UInt16 id = ZipUtil::get16BitValue(ptr, 0); ptr +=2;
Poco::UInt16 size = ZipUtil::get16BitValue(ptr, 0); ptr += 2;
if (id == ZipCommon::ZIP64_EXTRA_ID)
{
poco_assert(size >= 8);
if (getUncompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC)
{
setUncompressedSize(ZipUtil::get64BitValue(ptr, 0)); size -= 8; ptr += 8;
}
if (size >= 8 && getCompressedSizeFromHeader() == ZipCommon::ZIP64_MAGIC)
{
setCompressedSize(ZipUtil::get64BitValue(ptr, 0)); size -= 8; ptr += 8;
}
}
else
{
ptr += size;
}
}
}
}
@ -187,9 +226,7 @@ void ZipLocalFileHeader::setFileName(const std::string& fileName, bool isDirecto
}
void ZipLocalFileHeader::init( const Poco::Path& fName,
ZipCommon::CompressionMethod cm,
ZipCommon::CompressionLevel cl)
void ZipLocalFileHeader::init(const Poco::Path& fName, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl)
{
poco_assert (_fileName.empty());
setSearchCRCAndSizesAfterData(false);
@ -204,6 +241,10 @@ void ZipLocalFileHeader::init( const Poco::Path& fName,
}
else
setCompressionMethod(ZipCommon::CM_STORE);
if (_forceZip64)
setZip64Data();
_rawHeader[GENERAL_PURPOSE_POS+1] |= 0x08; // Set "language encoding flag" to indicate that filenames and paths are in UTF-8.
}

View File

@ -135,6 +135,8 @@ ZipStreamBuf::ZipStreamBuf(std::ostream& ostr, ZipLocalFileHeader& fileEntry, bo
else throw Poco::NotImplementedException("Unsupported compression method");
// now write the header to the ostr!
if (fileEntry.needsZip64())
fileEntry.setZip64Data();
std::string header = fileEntry.createHeader();
ostr.write(header.c_str(), static_cast<std::streamsize>(header.size()));
}
@ -198,8 +200,9 @@ int ZipStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
}
void ZipStreamBuf::close()
void ZipStreamBuf::close(Poco::UInt64& extraDataSize)
{
extraDataSize = 0;
if (_ptrOBuf && _pHeader)
{
_ptrOBuf->flush();
@ -217,20 +220,36 @@ void ZipStreamBuf::close()
// or fix the crc entries
if (_pHeader->searchCRCAndSizesAfterData())
{
ZipDataInfo info;
if (_pHeader->needsZip64())
{
ZipDataInfo64 info;
info.setCRC32(_crc32.checksum());
info.setUncompressedSize(_bytesWritten);
info.setCompressedSize(_ptrOHelper->bytesWritten());
extraDataSize = info.getFullHeaderSize();
_pOstr->write(info.getRawHeader(), static_cast<std::streamsize>(extraDataSize));
}
else
{
ZipDataInfo info;
info.setCRC32(_crc32.checksum());
info.setUncompressedSize(static_cast<Poco::UInt32>(_bytesWritten));
info.setCompressedSize(static_cast<Poco::UInt32>(_ptrOHelper->bytesWritten()));
_pOstr->write(info.getRawHeader(), static_cast<std::streamsize>(info.getFullHeaderSize()));
extraDataSize = info.getFullHeaderSize();
_pOstr->write(info.getRawHeader(), static_cast<std::streamsize>(extraDataSize));
}
}
else
{
poco_check_ptr (_pHeader);
_pHeader->setCRC(_crc32.checksum());
_pHeader->setUncompressedSize(_bytesWritten);
_pHeader->setCompressedSize(static_cast<Poco::UInt32>(_ptrOHelper->bytesWritten()));
_pHeader->setCompressedSize(_ptrOHelper->bytesWritten());
_pOstr->seekp(_pHeader->getStartPos(), std::ios_base::beg);
poco_assert (*_pOstr);
_pHeader->setStartPos(_pHeader->getStartPos()); // This resets EndPos now that compressed Size is known
if (_pHeader->hasExtraField()) // Update sizes in header extension.
_pHeader->setZip64Data();
std::string header = _pHeader->createHeader();
_pOstr->write(header.c_str(), static_cast<std::streamsize>(header.size()));
_pOstr->seekp(0, std::ios_base::end);
@ -297,10 +316,10 @@ ZipOutputStream::~ZipOutputStream()
}
void ZipOutputStream::close()
void ZipOutputStream::close(Poco::UInt64& extraDataSize)
{
flush();
_buf.close();
_buf.close(extraDataSize);
}

View File

@ -12,6 +12,7 @@
#include "CompressTest.h"
#include "ZipTest.h"
#include "Poco/Buffer.h"
#include "Poco/Zip/Compress.h"
#include "Poco/Zip/ZipManipulator.h"
#include "Poco/File.h"
@ -19,6 +20,8 @@
#include "CppUnit/TestCaller.h"
#include "CppUnit/TestSuite.h"
#include <fstream>
#undef min
#include <algorithm>
using namespace Poco::Zip;
@ -134,6 +137,57 @@ void CompressTest::testSetZipComment()
}
void CompressTest::createDataFile(const std::string& path, Poco::UInt64 size)
{
std::ofstream out(path.c_str(), std::ios::binary | std::ios::trunc);
assert( ! out.fail() );
Poco::Buffer<char> buffer(MB);
for(int i = 0; size != 0; i++) {
std::memset(buffer.begin(), i, buffer.size());
Poco::UInt64 bytesToWrite = std::min(size, static_cast<Poco::UInt64>(buffer.size()));
out.write(buffer.begin(), bytesToWrite);
assert( ! out.fail() );
size -= bytesToWrite;
}
out.flush();
assert( ! out.fail() );
out.close();
assert( ! out.fail() );
}
void CompressTest::testZip64()
{
std::map<std::string, Poco::UInt64> files;
files["data1.bin"] = static_cast<Poco::UInt64>(MB)*4096+1;
files["data2.bin"] = static_cast<Poco::UInt64>(MB)*16;
files["data3.bin"] = static_cast<Poco::UInt64>(MB)*4096-1;
for(std::map<std::string, Poco::UInt64>::const_iterator it = files.begin(); it != files.end(); it++)
{
createDataFile(it->first, it->second);
}
std::ofstream out("zip64.zip", std::ios::binary | std::ios::trunc);
Compress c(out, true, true);
for(std::map<std::string, Poco::UInt64>::const_iterator it = files.begin(); it != files.end(); it++)
{
const std::string& path = it->first;
c.addFile(path, path, ZipCommon::CM_STORE);
}
ZipArchive a(c.close());
for(std::map<std::string, Poco::UInt64>::const_iterator it = files.begin(); it != files.end(); it++)
{
const std::string& path = it->first;
Poco::UInt64 size = it->second;
ZipArchive::FileHeaders::const_iterator it2 = a.findHeader(path);
assert (it2 != a.headerEnd());
const Poco::Zip::ZipLocalFileHeader& file = it2->second;
assert(file.getUncompressedSize() == size);
assert(file.getCompressedSize() == size);
}
}
void CompressTest::setUp()
{
}
@ -154,6 +208,7 @@ CppUnit::Test* CompressTest::suite()
CppUnit_addTest(pSuite, CompressTest, testManipulatorDel);
CppUnit_addTest(pSuite, CompressTest, testManipulatorReplace);
CppUnit_addTest(pSuite, CompressTest, testSetZipComment);
CppUnit_addTest(pSuite, CompressTest, testZip64);
return pSuite;
}

View File

@ -33,6 +33,10 @@ public:
void testManipulatorReplace();
void testSetZipComment();
static const Poco::UInt64 MB = (1024*1024);
void createDataFile(const std::string& path, Poco::UInt64 size);
void testZip64();
void setUp();
void tearDown();

View File

@ -25,6 +25,8 @@
#include "Poco/StreamCopier.h"
#include "CppUnit/TestCaller.h"
#include "CppUnit/TestSuite.h"
#undef min
#include <algorithm>
#include <fstream>
#include <sstream>
@ -58,8 +60,8 @@ void ZipTest::testSkipSingleFile()
ZipCommon::CompressionMethod cm = hdr.getCompressionMethod();
assert (!hdr.isEncrypted());
Poco::DateTime aDate = hdr.lastModifiedAt();
Poco::UInt32 cS = hdr.getCompressedSize();
Poco::UInt32 uS = hdr.getUncompressedSize();
Poco::UInt64 cS = hdr.getCompressedSize();
Poco::UInt64 uS = hdr.getUncompressedSize();
const std::string& fileName = hdr.getFileName();
}
@ -164,6 +166,51 @@ void ZipTest::testDecompressFlat()
}
void ZipTest::verifyDataFile(const std::string& path, Poco::UInt64 size)
{
std::ifstream in(path.c_str(), std::ios::binary);
assert( ! in.fail() );
Poco::Buffer<char> buffer1(MB);
Poco::Buffer<char> buffer2(MB);
for (int i = 0; size != 0; i++)
{
std::memset(buffer1.begin(), i, buffer1.size());
std::memset(buffer2.begin(), 0, buffer2.size());
Poco::UInt64 bytesToRead = std::min(size, static_cast<Poco::UInt64>(buffer2.size()));
in.read(buffer2.begin(), bytesToRead);
assert(!in.fail() );
assert(std::memcmp(buffer1.begin(), buffer2.begin(), static_cast<std::size_t>(bytesToRead)) == 0);
size -= bytesToRead;
}
char c;
in.read(&c, 1);
assert ( in.eof() );
}
void ZipTest::testDecompressZip64()
{
std::map<std::string, Poco::UInt64> files;
files["data1.bin"] = static_cast<Poco::UInt64>(MB)*4096+1;
files["data2.bin"] = static_cast<Poco::UInt64>(MB)*16;
files["data3.bin"] = static_cast<Poco::UInt64>(MB)*4096-1;
for(std::map<std::string, Poco::UInt64>::const_iterator it = files.begin(); it != files.end(); it++)
{
Poco::File file(it->first);
if(file.exists())
file.remove();
}
std::ifstream in("zip64.zip", std::ios::binary);
Decompress c(in, ".");
c.decompressAllFiles();
for(std::map<std::string, Poco::UInt64>::const_iterator it = files.begin(); it != files.end(); it++)
{
verifyDataFile(it->first, it->second);
}
}
void ZipTest::onDecompressError(const void* pSender, std::pair<const Poco::Zip::ZipLocalFileHeader, const std::string>& info)
{
++_errCnt;
@ -191,5 +238,7 @@ CppUnit::Test* ZipTest::suite()
CppUnit_addTest(pSuite, ZipTest, testDecompressFlat);
CppUnit_addTest(pSuite, ZipTest, testCrcAndSizeAfterData);
CppUnit_addTest(pSuite, ZipTest, testCrcAndSizeAfterDataWithArchive);
CppUnit_addTest(pSuite, ZipTest, testDecompressZip64);
return pSuite;
}

View File

@ -35,6 +35,10 @@ public:
void testDecompressFlat();
static const Poco::UInt64 MB = (1024*1024);
void verifyDataFile(const std::string& path, Poco::UInt64 size);
void testDecompressZip64();
void setUp();
void tearDown();

View File

@ -20,9 +20,9 @@ CppUnit::Test* ZipTestSuite::suite()
{
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ZipTestSuite");
pSuite->addTest(CompressTest::suite());
pSuite->addTest(ZipTest::suite());
pSuite->addTest(PartialStreamTest::suite());
pSuite->addTest(CompressTest::suite());
return pSuite;
}

View File

@ -30,7 +30,7 @@ IPHONE_SDK_VERSION_MIN ?= $(patsubst %.sdk,%,$(patsubst $(IPHONE_SDK_ROOT_DIR)%,
POCO_TARGET_OSNAME ?= $(IPHONE_SDK)
POCO_TARGET_OSARCH ?= armv6
TOOL_PREFIX ?= /Developer/Platforms/$(IPHONE_SDK).platform/Developer/usr/bin
TOOL_PREFIX ?= $(shell xcode-select -print-path)/Platforms/$(IPHONE_SDK).platform/Developer/usr/bin
OSFLAGS ?= -arch $(POCO_TARGET_OSARCH) -isysroot $(IPHONE_SDK_BASE) -mthumb -miphoneos-version-min=$(IPHONE_SDK_VERSION_MIN)
#
@ -39,8 +39,8 @@ OSFLAGS ?= -arch $(POCO_TARGET_OSARCH) -isysroot $(IPHONE_SDK_BAS
# If GCC_VER is defined then use it.
# Otherwise select the latest version
#
CC = $(shell ls $(TOOL_PREFIX)/llvm-gcc-$(GCC_VER)* | tail -1)
CXX = $(shell ls $(TOOL_PREFIX)/llvm-g++-$(GCC_VER)* | tail -1)
CC = $(shell xcrun -find clang)
CXX = $(shell xcrun -find clang++)
LINK = $(CXX) -bind_at_load
LIB = libtool -static -o

View File

@ -0,0 +1,111 @@
# http://www.cmake.org/Wiki/CMake_Useful_Variables :
# CMAKE_BUILD_TYPE
# Choose the type of build. CMake has default flags for these:
#
# * None (CMAKE_C_FLAGS or CMAKE_CXX_FLAGS used)
# * Debug (CMAKE_C_FLAGS_DEBUG or CMAKE_CXX_FLAGS_DEBUG)
# * Release (CMAKE_C_FLAGS_RELEASE or CMAKE_CXX_FLAGS_RELEASE)
# * RelWithDebInfo (CMAKE_C_FLAGS_RELWITHDEBINFO or CMAKE_CXX_FLAGS_RELWITHDEBINFO
# * MinSizeRel (CMAKE_C_FLAGS_MINSIZEREL or CMAKE_CXX_FLAGS_MINSIZEREL)
# Setting CXX Flag /MD or /MT and POSTFIX values i.e MDd / MD / MTd / MT / d
#
# For visual studio the library naming is as following:
# Dynamic libraries:
# - PocoX.dll for release library
# - PocoXd.dll for debug library
#
# Static libraries:
# - PocoXmd.lib for /MD release build
# - PocoXtmt.lib for /MT release build
#
# - PocoXmdd.lib for /MD debug build
# - PocoXmtd.lib for /MT debug build
if(MSVC)
if(POCO_MT)
set(CompilerFlags
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
)
foreach(CompilerFlag ${CompilerFlags})
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()
set(STATIC_POSTFIX "mt" CACHE STRING "Set static library postfix" FORCE)
else(POCO_MT)
set(STATIC_POSTFIX "md" CACHE STRING "Set static library postfix" FORCE)
endif(POCO_MT)
else(MSVC)
# Other compilers then MSVC don't have a static STATIC_POSTFIX at the moment
set(STATIC_POSTFIX "" CACHE STRING "Set static library postfix" FORCE)
endif(MSVC)
# Add a d postfix to the debug libraries
if(POCO_STATIC)
set(CMAKE_DEBUG_POSTFIX "${STATIC_POSTFIX}d" CACHE STRING "Set Debug library postfix" FORCE)
set(CMAKE_RELEASE_POSTFIX "${STATIC_POSTFIX}" CACHE STRING "Set Release library postfix" FORCE)
set(CMAKE_MINSIZEREL_POSTFIX "${STATIC_POSTFIX}" CACHE STRING "Set MinSizeRel library postfix" FORCE)
set(CMAKE_RELWITHDEBINFO_POSTFIX "${STATIC_POSTFIX}d" CACHE STRING "Set RelWithDebInfo library postfix" FORCE)
else(POCO_STATIC)
set(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Set Debug library postfix" FORCE)
set(CMAKE_RELEASE_POSTFIX "" CACHE STRING "Set Release library postfix" FORCE)
set(CMAKE_MINSIZEREL_POSTFIX "" CACHE STRING "Set MinSizeRel library postfix" FORCE)
set(CMAKE_RELWITHDEBINFO_POSTFIX "d" CACHE STRING "Set RelWithDebInfo library postfix" FORCE)
endif()
# OS Detection
include(CheckTypeSize)
find_package(Cygwin)
if(WIN32)
add_definitions( -DPOCO_OS_FAMILY_WINDOWS -DUNICODE -D_UNICODE -D__LCC__) #__LCC__ define used by MySQL.h
endif(WIN32)
if (UNIX AND NOT ANDROID )
add_definitions( -DPOCO_OS_FAMILY_UNIX )
# Standard 'must be' defines
if (APPLE)
add_definitions( -DPOCO_HAVE_IPv6 -DPOCO_NO_STAT64)
set(SYSLIBS dl)
else (APPLE)
add_definitions( -D_XOPEN_SOURCE=500 -D_REENTRANT -D_THREAD_SAFE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64)
set(SYSLIBS pthread dl rt)
endif (APPLE)
endif(UNIX AND NOT ANDROID )
if (CMAKE_SYSTEM MATCHES "SunOS")
add_definitions( -DPOCO_OS_FAMILY_UNIX )
# Standard 'must be' defines
add_definitions( -D_XOPEN_SOURCE=500 -D_REENTRANT -D_THREAD_SAFE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 )
set(SYSLIBS pthread socket xnet nsl resolv rt dl)
endif(CMAKE_SYSTEM MATCHES "SunOS")
if (CMAKE_COMPILER_IS_MINGW)
add_definitions(-DWC_NO_BEST_FIT_CHARS=0x400 -DPOCO_WIN32_UTF8)
add_definitions(-D_WIN32 -DMINGW32 -DWINVER=0x500 -DODBCVER=0x0300 -DPOCO_THREAD_STACK_SIZE)
endif (CMAKE_COMPILER_IS_MINGW)
if (CYGWIN)
# add_definitions(-DWC_NO_BEST_FIT_CHARS=0x400 -DPOCO_WIN32_UTF8)
endif (CYGWIN)
# SunPro C++
if (${CMAKE_CXX_COMPILER_ID} MATCHES "SunPro")
add_definitions( -D_BSD_SOURCE -library=stlport4)
endif (${CMAKE_CXX_COMPILER_ID} MATCHES "SunPro")
# iOS
if (IOS)
add_definitions( -DPOCO_HAVE_IPv6 -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_STAT64 -DPOCO_NO_SHAREDLIBS -DPOCO_NO_NET_IFTYPES )
endif(IOS)
#Android
if (ANDROID)
add_definitions( -DPOCO_ANDROID -DPOCO_NO_FPENVIRONMENT -DPOCO_NO_WSTRING -DPOCO_NO_SHAREDMEMORY )
endif(ANDROID)

View File

@ -1,3 +1,6 @@
SET(BINDIR32_ENV_NAME "ProgramFiles(x86)")
SET(BINDIR32 $ENV{${BINDIR32_ENV_NAME}})
find_path(MYSQL_INCLUDE_DIR mysql.h
/usr/include/mysql
/usr/local/include/mysql
@ -8,6 +11,7 @@ find_path(MYSQL_INCLUDE_DIR mysql.h
$ENV{MYSQL_INCLUDE_DIR}
$ENV{MYSQL_DIR}/include
$ENV{ProgramFiles}/MySQL/*/include
${BINDIR32}/MySQL/include
$ENV{SystemDrive}/MySQL/*/include)
if (WIN32)
@ -26,6 +30,7 @@ if (WIN32)
$ENV{MYSQL_DIR}/libmysql/${libsuffixBuild}
$ENV{MYSQL_DIR}/client/${libsuffixBuild}
$ENV{ProgramFiles}/MySQL/*/lib/${libsuffixDist}
${BINDIR32}/MySQL/lib
$ENV{SystemDrive}/MySQL/*/lib/${libsuffixDist})
else (WIN32)
find_library(MYSQL_LIB NAMES mysqlclient_r