Mercurial > hg > orthanc
annotate Core/Compression/ZipWriter.cpp @ 134:bdc60d16cc98
improved cmake
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 09 Oct 2012 11:58:22 +0200 |
parents | 7593b57dc1bf |
children | fe180eae201d |
rev | line source |
---|---|
81 | 1 #include "ZipWriter.h" |
2 | |
102
7593b57dc1bf
switch to google log
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
81
diff
changeset
|
3 #include "../../Resources/minizip/zip.h" |
81 | 4 #include <boost/date_time/posix_time/posix_time.hpp> |
5 | |
6 #include "../OrthancException.h" | |
7 | |
8 | |
9 static void PrepareFileInfo(zip_fileinfo& zfi) | |
10 { | |
11 memset(&zfi, 0, sizeof(zfi)); | |
12 | |
13 using namespace boost::posix_time; | |
14 ptime now = second_clock::local_time(); | |
15 | |
16 boost::gregorian::date today = now.date(); | |
17 ptime midnight(today); | |
18 | |
19 time_duration sinceMidnight = now - midnight; | |
20 zfi.tmz_date.tm_sec = sinceMidnight.seconds(); // seconds after the minute - [0,59] | |
21 zfi.tmz_date.tm_min = sinceMidnight.minutes(); // minutes after the hour - [0,59] | |
22 zfi.tmz_date.tm_hour = sinceMidnight.hours(); // hours since midnight - [0,23] | |
23 | |
24 // http://www.boost.org/doc/libs/1_35_0/doc/html/boost/gregorian/greg_day.html | |
25 zfi.tmz_date.tm_mday = today.day(); // day of the month - [1,31] | |
26 | |
27 // http://www.boost.org/doc/libs/1_35_0/doc/html/boost/gregorian/greg_month.html | |
28 zfi.tmz_date.tm_mon = today.month() - 1; // months since January - [0,11] | |
29 | |
30 // http://www.boost.org/doc/libs/1_35_0/doc/html/boost/gregorian/greg_year.html | |
31 zfi.tmz_date.tm_year = today.year(); // years - [1980..2044] | |
32 } | |
33 | |
34 | |
35 | |
36 namespace Orthanc | |
37 { | |
38 struct ZipWriter::PImpl | |
39 { | |
40 zipFile file_; | |
41 }; | |
42 | |
43 ZipWriter::ZipWriter() : pimpl_(new PImpl) | |
44 { | |
45 compressionLevel_ = 6; | |
46 hasFileInZip_ = false; | |
47 | |
48 pimpl_->file_ = NULL; | |
49 } | |
50 | |
51 ZipWriter::~ZipWriter() | |
52 { | |
53 Close(); | |
54 } | |
55 | |
56 void ZipWriter::Close() | |
57 { | |
58 if (IsOpen()) | |
59 { | |
60 zipClose(pimpl_->file_, "Created by Orthanc"); | |
61 pimpl_->file_ = NULL; | |
62 hasFileInZip_ = false; | |
63 } | |
64 } | |
65 | |
66 bool ZipWriter::IsOpen() const | |
67 { | |
68 return pimpl_->file_ != NULL; | |
69 } | |
70 | |
71 void ZipWriter::Open() | |
72 { | |
73 if (IsOpen()) | |
74 { | |
75 return; | |
76 } | |
77 | |
78 if (path_.size() == 0) | |
79 { | |
80 throw OrthancException("Please call SetOutputPath() before creating the file"); | |
81 } | |
82 | |
83 hasFileInZip_ = false; | |
84 pimpl_->file_ = zipOpen64(path_.c_str(), APPEND_STATUS_CREATE); | |
85 if (!pimpl_->file_) | |
86 { | |
87 throw OrthancException(ErrorCode_CannotWriteFile); | |
88 } | |
89 } | |
90 | |
91 void ZipWriter::SetOutputPath(const char* path) | |
92 { | |
93 Close(); | |
94 path_ = path; | |
95 } | |
96 | |
97 void ZipWriter::SetCompressionLevel(uint8_t level) | |
98 { | |
99 if (level >= 10) | |
100 { | |
101 throw OrthancException("ZIP compression level must be between 0 (no compression) and 9 (highest compression"); | |
102 } | |
103 | |
104 compressionLevel_ = level; | |
105 } | |
106 | |
107 void ZipWriter::CreateFileInZip(const char* path) | |
108 { | |
109 Open(); | |
110 | |
111 zip_fileinfo zfi; | |
112 PrepareFileInfo(zfi); | |
113 | |
114 if (zipOpenNewFileInZip64(pimpl_->file_, path, | |
115 &zfi, | |
116 NULL, 0, | |
117 NULL, 0, | |
118 "", // Comment | |
119 Z_DEFLATED, | |
120 compressionLevel_, 1) != 0) | |
121 { | |
122 throw OrthancException(ErrorCode_CannotWriteFile); | |
123 } | |
124 | |
125 hasFileInZip_ = true; | |
126 } | |
127 | |
128 | |
129 void ZipWriter::Write(const std::string& data) | |
130 { | |
131 if (data.size()) | |
132 { | |
133 Write(&data[0], data.size()); | |
134 } | |
135 } | |
136 | |
137 | |
138 void ZipWriter::Write(const char* data, size_t length) | |
139 { | |
140 if (!hasFileInZip_) | |
141 { | |
142 throw OrthancException("Call first CreateFileInZip()"); | |
143 } | |
144 | |
145 const size_t maxBytesInAStep = std::numeric_limits<int32_t>::max(); | |
146 | |
147 while (length > 0) | |
148 { | |
149 int bytes = static_cast<int32_t>(length <= maxBytesInAStep ? length : maxBytesInAStep); | |
150 | |
151 if (zipWriteInFileInZip(pimpl_->file_, data, bytes)) | |
152 { | |
153 throw OrthancException(ErrorCode_CannotWriteFile); | |
154 } | |
155 | |
156 data += bytes; | |
157 length -= bytes; | |
158 } | |
159 } | |
160 } |