annotate OrthancFramework/Sources/Compression/ZipReader.cpp @ 5724:b7bf515864a2 find-refactoring tip

added safeguard
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 19 Jul 2024 10:25:03 +0200
parents f7adfb22e20e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
1 /**
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
2 * Orthanc - A Lightweight, RESTful DICOM Store
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
4 * Department, University Hospital of Liege, Belgium
5640
f7adfb22e20e updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 5485
diff changeset
5 * Copyright (C) 2017-2023 Osimis S.A., Belgium
f7adfb22e20e updated copyright, as Orthanc Team now replaces Osimis
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 5485
diff changeset
6 * Copyright (C) 2024-2024 Orthanc Team SRL, Belgium
5485
48b8dae6dc77 upgrade to year 2024
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 5185
diff changeset
7 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
8 *
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
9 * This program is free software: you can redistribute it and/or
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
10 * modify it under the terms of the GNU Lesser General Public License
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
11 * as published by the Free Software Foundation, either version 3 of
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
12 * the License, or (at your option) any later version.
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
13 *
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
14 * This program is distributed in the hope that it will be useful, but
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
17 * Lesser General Public License for more details.
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
18 *
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
19 * You should have received a copy of the GNU Lesser General Public
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
20 * License along with this program. If not, see
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
21 * <http://www.gnu.org/licenses/>.
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
22 **/
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
23
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
24
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
25 #include "../PrecompiledHeaders.h"
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
26
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
27 #ifndef NOMINMAX
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
28 #define NOMINMAX
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
29 #endif
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
30
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
31 #include "ZipReader.h"
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
32
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
33 #include "../OrthancException.h"
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
34 #include "../../Resources/ThirdParty/minizip/unzip.h"
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
35
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
36 #if ORTHANC_SANDBOXED != 1
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
37 # include "../SystemToolbox.h"
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
38 #endif
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
39
4363
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
40
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
41 /**
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
42 * I have not been able to correctly define "ssize_t" on all versions
4751
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4437
diff changeset
43 * of Visual Studio. As a consequence, I preferred to switch "ssize_t"
4363
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
44 * to "SSIZE_T", that is properly defined on both MSVC 2008 and 2015.
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
45 * I define the macro "SSIZE_T" as an alias to "ssize_t" on
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
46 * POSIX-compliant platforms that wouldn't have "SSIZE_T" defined.
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
47 **/
4359
074f37013186 fix ZipReader.cpp for msvc
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4356
diff changeset
48 #if defined(_MSC_VER)
4360
4301722b3225 fix for msvc2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4359
diff changeset
49 # include <BaseTsd.h> // Definition of SSIZE_T
4363
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
50 #else
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
51 # if !defined(SSIZE_T)
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
52 typedef ssize_t SSIZE_T;
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
53 # endif
4359
074f37013186 fix ZipReader.cpp for msvc
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4356
diff changeset
54 #endif
074f37013186 fix ZipReader.cpp for msvc
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4356
diff changeset
55
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
56 #include <string.h>
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
57
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
58
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
59 namespace Orthanc
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
60 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
61 // ZPOS64_T corresponds to "uint64_t"
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
62
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
63 class ZipReader::MemoryBuffer : public boost::noncopyable
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
64 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
65 private:
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
66 const uint8_t* content_;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
67 size_t size_;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
68 size_t pos_;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
69
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
70 public:
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
71 MemoryBuffer(const void* p,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
72 size_t size) :
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
73 content_(reinterpret_cast<const uint8_t*>(p)),
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
74 size_(size),
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
75 pos_(0)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
76 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
77 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
78
4356
18c94a82f3d4 cppcheck
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4355
diff changeset
79 explicit MemoryBuffer(const std::string& s) :
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
80 content_(s.empty() ? NULL : reinterpret_cast<const uint8_t*>(s.c_str())),
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
81 size_(s.size()),
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
82 pos_(0)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
83 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
84 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
85
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
86 // Returns the number of bytes actually read
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
87 uLong Read(void *target,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
88 uLong size)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
89 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
90 if (size <= 0)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
91 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
92 return 0;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
93 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
94 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
95 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
96 size_t s = static_cast<size_t>(size);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
97 if (s + pos_ > size_)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
98 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
99 s = size_ - pos_;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
100 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
101
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
102 if (s != 0)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
103 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
104 memcpy(target, content_ + pos_, s);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
105 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
106
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
107 pos_ += s;
4360
4301722b3225 fix for msvc2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4359
diff changeset
108 return static_cast<uLong>(s);
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
109 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
110 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
111
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
112 ZPOS64_T Tell() const
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
113 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
114 return static_cast<ZPOS64_T>(pos_);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
115 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
116
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
117 long Seek(ZPOS64_T offset,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
118 int origin)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
119 {
4363
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
120 SSIZE_T next;
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
121
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
122 switch (origin)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
123 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
124 case ZLIB_FILEFUNC_SEEK_CUR:
4363
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
125 next = static_cast<SSIZE_T>(offset) + static_cast<SSIZE_T>(pos_);
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
126 break;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
127
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
128 case ZLIB_FILEFUNC_SEEK_SET:
4363
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
129 next = static_cast<SSIZE_T>(offset);
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
130 break;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
131
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
132 case ZLIB_FILEFUNC_SEEK_END:
4363
1382c908d67c trying to fix msvc build errors for plugins while compiling ZipReader.cpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4362
diff changeset
133 next = static_cast<SSIZE_T>(offset) + static_cast<SSIZE_T>(size_);
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
134 break;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
135
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
136 default: // Should never occur
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
137 return 1; // Error
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
138 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
139
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
140 if (next < 0)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
141 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
142 pos_ = 0;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
143 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
144 else if (next >= static_cast<long>(size_))
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
145 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
146 pos_ = size_;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
147 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
148 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
149 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
150 pos_ = static_cast<long>(next);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
151 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
152
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
153 return 0;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
154 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
155
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
156
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
157 static voidpf OpenWrapper(voidpf opaque,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
158 const void* filename,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
159 int mode)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
160 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
161 // Don't return NULL to make "unzip.c" happy
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
162 return opaque;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
163 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
164
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
165 static uLong ReadWrapper(voidpf opaque,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
166 voidpf stream,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
167 void* buf,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
168 uLong size)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
169 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
170 assert(opaque != NULL);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
171 return reinterpret_cast<MemoryBuffer*>(opaque)->Read(buf, size);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
172 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
173
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
174 static ZPOS64_T TellWrapper(voidpf opaque,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
175 voidpf stream)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
176 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
177 assert(opaque != NULL);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
178 return reinterpret_cast<MemoryBuffer*>(opaque)->Tell();
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
179 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
180
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
181 static long SeekWrapper(voidpf opaque,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
182 voidpf stream,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
183 ZPOS64_T offset,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
184 int origin)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
185 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
186 assert(opaque != NULL);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
187 return reinterpret_cast<MemoryBuffer*>(opaque)->Seek(offset, origin);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
188 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
189
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
190 static int CloseWrapper(voidpf opaque,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
191 voidpf stream)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
192 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
193 return 0;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
194 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
195
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
196 static int TestErrorWrapper(voidpf opaque,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
197 voidpf stream)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
198 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
199 return 0; // ??
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
200 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
201 };
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
202
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
203
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
204
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
205 ZipReader* ZipReader::CreateFromMemory(const std::string& buffer)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
206 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
207 if (buffer.empty())
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
208 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
209 return CreateFromMemory(NULL, 0);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
210 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
211 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
212 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
213 return CreateFromMemory(buffer.c_str(), buffer.size());
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
214 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
215 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
216
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
217
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
218 bool ZipReader::IsZipMemoryBuffer(const void* buffer,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
219 size_t size)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
220 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
221 if (size < 4)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
222 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
223 return false;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
224 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
225 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
226 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
227 const uint8_t* c = reinterpret_cast<const uint8_t*>(buffer);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
228 return (c[0] == 0x50 && // 'P'
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
229 c[1] == 0x4b && // 'K'
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
230 ((c[2] == 0x03 && c[3] == 0x04) ||
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
231 (c[2] == 0x05 && c[3] == 0x06) ||
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
232 (c[2] == 0x07 && c[3] == 0x08)));
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
233 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
234 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
235
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
236
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
237 bool ZipReader::IsZipMemoryBuffer(const std::string& content)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
238 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
239 if (content.empty())
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
240 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
241 return false;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
242 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
243 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
244 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
245 return IsZipMemoryBuffer(content.c_str(), content.size());
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
246 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
247 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
248
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
249
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
250 #if ORTHANC_SANDBOXED != 1
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
251 bool ZipReader::IsZipFile(const std::string& path)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
252 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
253 std::string content;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
254 SystemToolbox::ReadFileRange(content, path, 0, 4,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
255 false /* don't throw if file is too small */);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
256
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
257 return IsZipMemoryBuffer(content);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
258 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
259 #endif
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
260
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
261
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
262 struct ZipReader::PImpl
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
263 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
264 unzFile unzip_;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
265 std::unique_ptr<MemoryBuffer> reader_;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
266 bool done_;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
267
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
268 PImpl() :
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
269 unzip_(NULL),
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
270 done_(true)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
271 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
272 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
273 };
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
274
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
275
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
276 ZipReader::ZipReader() :
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
277 pimpl_(new PImpl)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
278 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
279 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
280
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
281
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
282 ZipReader::~ZipReader()
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
283 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
284 if (pimpl_->unzip_ != NULL)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
285 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
286 unzClose(pimpl_->unzip_);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
287 pimpl_->unzip_ = NULL;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
288 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
289 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
290
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
291
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
292 uint64_t ZipReader::GetFilesCount() const
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
293 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
294 assert(pimpl_->unzip_ != NULL);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
295
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
296 unz_global_info64_s info;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
297
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
298 if (unzGetGlobalInfo64(pimpl_->unzip_, &info) == 0)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
299 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
300 return info.number_entry;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
301 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
302 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
303 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
304 throw OrthancException(ErrorCode_BadFileFormat);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
305 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
306 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
307
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
308
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
309 void ZipReader::SeekFirst()
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
310 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
311 assert(pimpl_->unzip_ != NULL);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
312 pimpl_->done_ = (unzGoToFirstFile(pimpl_->unzip_) != 0);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
313 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
314
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
315
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
316 bool ZipReader::ReadNextFile(std::string& filename,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
317 std::string& content)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
318 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
319 assert(pimpl_->unzip_ != NULL);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
320
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
321 if (pimpl_->done_)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
322 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
323 return false;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
324 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
325 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
326 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
327 unz_file_info64_s info;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
328 if (unzGetCurrentFileInfo64(pimpl_->unzip_, &info, NULL, 0, NULL, 0, NULL, 0) != 0)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
329 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
330 throw OrthancException(ErrorCode_BadFileFormat);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
331 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
332
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
333 filename.resize(info.size_filename);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
334 if (!filename.empty() &&
4360
4301722b3225 fix for msvc2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4359
diff changeset
335 unzGetCurrentFileInfo64(pimpl_->unzip_, &info, &filename[0],
4301722b3225 fix for msvc2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4359
diff changeset
336 static_cast<uLong>(filename.size()), NULL, 0, NULL, 0) != 0)
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
337 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
338 throw OrthancException(ErrorCode_BadFileFormat);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
339 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
340
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
341 content.resize(info.uncompressed_size);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
342
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
343 if (!content.empty())
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
344 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
345 if (unzOpenCurrentFile(pimpl_->unzip_) == 0)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
346 {
4360
4301722b3225 fix for msvc2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4359
diff changeset
347 bool success = (unzReadCurrentFile(pimpl_->unzip_, &content[0],
4301722b3225 fix for msvc2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 4359
diff changeset
348 static_cast<uLong>(content.size())) != 0);
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
349
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
350 if (unzCloseCurrentFile(pimpl_->unzip_) != 0 ||
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
351 !success)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
352 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
353 throw OrthancException(ErrorCode_BadFileFormat);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
354 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
355 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
356 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
357 {
4800
588fa6fb32ca more detailed error message for unsupported zip files
Alain Mazy <am@osimis.io>
parents: 4751
diff changeset
358 throw OrthancException(ErrorCode_BadFileFormat, "Invalid file or unsupported compression method (e.g. Deflate64)");
4355
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
359 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
360 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
361
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
362 pimpl_->done_ = (unzGoToNextFile(pimpl_->unzip_) != 0);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
363
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
364 return true;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
365 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
366 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
367
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
368
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
369 ZipReader* ZipReader::CreateFromMemory(const void* buffer,
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
370 size_t size)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
371 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
372 if (!IsZipMemoryBuffer(buffer, size))
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
373 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
374 throw OrthancException(ErrorCode_BadFileFormat, "The memory buffer doesn't contain a ZIP archive");
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
375 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
376 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
377 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
378 std::unique_ptr<ZipReader> reader(new ZipReader);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
379
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
380 reader->pimpl_->reader_.reset(new MemoryBuffer(buffer, size));
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
381 if (reader->pimpl_->reader_.get() == NULL)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
382 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
383 throw OrthancException(ErrorCode_InternalError);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
384 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
385
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
386 zlib_filefunc64_def funcs;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
387 memset(&funcs, 0, sizeof(funcs));
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
388
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
389 funcs.opaque = reader->pimpl_->reader_.get();
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
390 funcs.zopen64_file = MemoryBuffer::OpenWrapper;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
391 funcs.zread_file = MemoryBuffer::ReadWrapper;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
392 funcs.ztell64_file = MemoryBuffer::TellWrapper;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
393 funcs.zseek64_file = MemoryBuffer::SeekWrapper;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
394 funcs.zclose_file = MemoryBuffer::CloseWrapper;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
395 funcs.zerror_file = MemoryBuffer::TestErrorWrapper;
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
396
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
397 reader->pimpl_->unzip_ = unzOpen2_64(NULL, &funcs);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
398 if (reader->pimpl_->unzip_ == NULL)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
399 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
400 throw OrthancException(ErrorCode_BadFileFormat, "Cannot open ZIP archive from memory buffer");
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
401 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
402 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
403 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
404 reader->SeekFirst();
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
405 return reader.release();
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
406 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
407 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
408 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
409
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
410
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
411 #if ORTHANC_SANDBOXED != 1
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
412 ZipReader* ZipReader::CreateFromFile(const std::string& path)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
413 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
414 if (!IsZipFile(path))
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
415 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
416 throw OrthancException(ErrorCode_BadFileFormat, "The file doesn't contain a ZIP archive: " + path);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
417 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
418 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
419 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
420 std::unique_ptr<ZipReader> reader(new ZipReader);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
421
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
422 reader->pimpl_->unzip_ = unzOpen64(path.c_str());
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
423 if (reader->pimpl_->unzip_ == NULL)
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
424 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
425 throw OrthancException(ErrorCode_BadFileFormat, "Cannot open ZIP archive from file: " + path);
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
426 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
427 else
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
428 {
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
429 reader->SeekFirst();
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
430 return reader.release();
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
431 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
432 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
433 }
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
434 #endif
460a71988208 new class: ZipReader
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
435 }