1//
2// Compress.h
3//
4// Library: Zip
5// Package: Zip
6// Module: Compress
7//
8// Definition of the Compress class.
9//
10// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Zip_Compress_INCLUDED
18#define Zip_Compress_INCLUDED
19
20
21#include "Poco/Zip/Zip.h"
22#include "Poco/Zip/ZipArchive.h"
23#include "Poco/FIFOEvent.h"
24#include <istream>
25#include <ostream>
26#include <set>
27
28
29namespace Poco {
30namespace Zip {
31
32
33class Zip_API Compress
34 /// Compresses a directory or files as zip.
35{
36public:
37 Poco::FIFOEvent<const ZipLocalFileHeader> EDone;
38
39 Compress(std::ostream& out, bool seekableOut, bool forceZip64 = false);
40 /// seekableOut determines how we write the zip, setting it to true is recommended for local files (smaller zip file),
41 /// if you are compressing directly to a network, you MUST set it to false
42 /// 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
43 /// if seekableOut is true in case the compressed or uncompressed size exceeds 32 bits.
44
45 ~Compress();
46
47 void addFile(std::istream& input, const Poco::DateTime& lastModifiedAt, const Poco::Path& fileName, ZipCommon::CompressionMethod cm = ZipCommon::CM_DEFLATE, ZipCommon::CompressionLevel cl = ZipCommon::CL_MAXIMUM);
48 /// Adds a single file to the Zip File. fileName must not be a directory name.
49
50 void addFile(const Poco::Path& file, const Poco::Path& fileName, ZipCommon::CompressionMethod cm = ZipCommon::CM_DEFLATE, ZipCommon::CompressionLevel cl = ZipCommon::CL_MAXIMUM);
51 /// Adds a single file to the Zip File. fileName must not be a directory name. The file must exist physically!
52
53 void addDirectory(const Poco::Path& entryName, const Poco::DateTime& lastModifiedAt);
54 /// Adds a directory entry excluding all children to the Zip file, entryName must not be empty.
55
56 void addRecursive(const Poco::Path& entry, ZipCommon::CompressionLevel cl = ZipCommon::CL_MAXIMUM, bool excludeRoot = true, const Poco::Path& name = Poco::Path());
57 /// Adds a directory entry recursively to the zip file, set excludeRoot to false to exclude the parent directory.
58 /// If excludeRoot is true you can specify an empty name to add the files as relative files
59
60 void addRecursive(const Poco::Path& entry, ZipCommon::CompressionMethod cm, ZipCommon::CompressionLevel cl = ZipCommon::CL_MAXIMUM, bool excludeRoot = true, const Poco::Path& name = Poco::Path());
61 /// Adds a directory entry recursively to the zip file, set excludeRoot to false to exclude the parent directory.
62 /// If excludeRoot is true you can specify an empty name to add the files as relative files
63
64 void setZipComment(const std::string& comment);
65 /// Sets the Zip file comment.
66
67 const std::string& getZipComment() const;
68 /// Returns the Zip file comment.
69
70 ZipArchive close();
71 /// Finalizes the ZipArchive, closes it.
72
73 void setStoreExtensions(const std::set<std::string>& extensions);
74 /// Sets the file extensions for which the CM_STORE compression method
75 /// is used if CM_AUTO is specified in addFile() or addRecursive().
76 /// For all other extensions, CM_DEFLATE is used. This is used to avoid
77 /// double compression of already compressed file formats, which usually
78 /// leads to worse results. Extensions will be converted to lower case.
79 ///
80 /// The default extensions are:
81 /// - gif
82 /// - jpg
83 /// - jpeg
84 /// - png
85
86 const std::set<std::string>& getStoreExtensions() const;
87 /// Returns the file extensions for which the CM_STORE compression method
88 /// is used if CM_AUTO is specified in addFile() or addRecursive().
89 ///
90 /// See setStoreExtensions() for more information.
91
92private:
93 enum
94 {
95 COMPRESS_CHUNK_SIZE = 8192
96 };
97
98 Compress(const Compress&);
99 Compress& operator=(const Compress&);
100
101 void addEntry(std::istream& input, const Poco::DateTime& lastModifiedAt, const Poco::Path& fileName, ZipCommon::CompressionMethod cm = ZipCommon::CM_DEFLATE, ZipCommon::CompressionLevel cl = ZipCommon::CL_MAXIMUM);
102 /// Either adds a file or a single directory entry (excluding subchildren) to the Zip file. the compression level will be ignored
103 /// for directories.
104
105 void addFileRaw(std::istream& in, const ZipLocalFileHeader& hdr, const Poco::Path& fileName);
106 /// copys an already compressed ZipEntry from in
107
108private:
109 std::set<std::string> _storeExtensions;
110 std::ostream& _out;
111 bool _seekableOut;
112 bool _forceZip64;
113 ZipArchive::FileHeaders _files;
114 ZipArchive::FileInfos _infos;
115 ZipArchive::DirectoryInfos _dirs;
116 ZipArchive::DirectoryInfos64 _dirs64;
117 Poco::UInt64 _offset;
118 std::string _comment;
119
120 friend class Keep;
121 friend class Rename;
122};
123
124
125//
126// inlines
127//
128
129
130inline void Compress::setZipComment(const std::string& comment)
131{
132 _comment = comment;
133}
134
135
136inline const std::string& Compress::getZipComment() const
137{
138 return _comment;
139}
140
141
142inline const std::set<std::string>& Compress::getStoreExtensions() const
143{
144 return _storeExtensions;
145}
146
147
148} } // namespace Poco::Zip
149
150
151#endif // Zip_Compress_INCLUDED
152