4#include "Stroika/Foundation/StroikaPreComp.h"
6#if qStroika_HasComponent_zlib
11#include "Stroika/Foundation/DataExchange/Archive/Zip/Private_minizip_.h"
13#include "Stroika/Foundation/Streams/MemoryStream.h"
21using namespace Stroika::Foundation::DataExchange::Archive;
23using namespace Stroika::Foundation::Streams;
27#if qStroika_HasComponent_zlib
28using namespace Stroika::Foundation::DataExchange::Archive::Zip::PrivateMinizip_;
31 void ThrowIfMinizipErr_ (
int err,
const String& doing)
33 if (err != UNZ_OK) [[unlikely]] {
40 struct MyZipLibInStream_ final : zlib_filefunc64_def {
42#if qStroika_Foundation_Debug_AssertionsChecked
48 this->zopen64_file = [] (voidpf opaqueStream,
const void* ,
int ) -> voidpf {
49 MyZipLibInStream_* myThis =
reinterpret_cast<MyZipLibInStream_*
> (opaqueStream);
50#if qStroika_Foundation_Debug_AssertionsChecked
51 Assert (not myThis->fOpened_);
52 myThis->fOpened_ =
true;
56 this->zread_file = [] (voidpf opaqueStream, [[maybe_unused]] voidpf stream,
void* buf, uLong size) -> uLong {
57 Require (opaqueStream == stream);
58 MyZipLibInStream_* myThis =
reinterpret_cast<MyZipLibInStream_*
> (opaqueStream);
59#if qStroika_Foundation_Debug_AssertionsChecked
60 Assert (myThis->fOpened_);
62 size_t sz = myThis->fInStream_.ReadBlocking (span{
reinterpret_cast<byte*
> (buf), size}).size ();
64 return static_cast<uLong
> (sz);
66 this->zwrite_file = [] (voidpf , voidpf ,
const void* , uLong ) -> uLong {
68 return static_cast<uLong
> (UNZ_PARAMERROR);
70 this->ztell64_file = [] (voidpf opaqueStream, [[maybe_unused]] voidpf stream) -> ZPOS64_T {
71 Require (opaqueStream == stream);
72 MyZipLibInStream_* myThis =
reinterpret_cast<MyZipLibInStream_*
> (opaqueStream);
73#if qStroika_Foundation_Debug_AssertionsChecked
74 Assert (myThis->fOpened_);
76 return myThis->fInStream_.GetOffset ();
78 this->zseek64_file = [] (voidpf opaqueStream, [[maybe_unused]] voidpf stream, ZPOS64_T offset,
int origin) ->
long {
79 Require (opaqueStream == stream);
80 MyZipLibInStream_* myThis =
reinterpret_cast<MyZipLibInStream_*
> (opaqueStream);
81#if qStroika_Foundation_Debug_AssertionsChecked
82 Assert (myThis->fOpened_);
85 case ZLIB_FILEFUNC_SEEK_SET:
86 myThis->fInStream_.Seek (offset);
88 case ZLIB_FILEFUNC_SEEK_CUR:
89 myThis->fInStream_.Seek (eFromCurrent, offset);
91 case ZLIB_FILEFUNC_SEEK_END:
92 myThis->fInStream_.Seek (eFromEnd, offset);
96 return UNZ_PARAMERROR;
100 this->zclose_file = [] ([[maybe_unused]] voidpf opaqueStream, [[maybe_unused]] voidpf stream) ->
int {
101#if qStroika_Foundation_Debug_AssertionsChecked
102 Require (opaqueStream == stream);
103 MyZipLibInStream_* myThis =
reinterpret_cast<MyZipLibInStream_*
> (opaqueStream);
104 Assert (myThis->fOpened_);
105 myThis->fOpened_ =
false;
109 this->zerror_file = [] (voidpf opaqueStream, [[maybe_unused]] voidpf stream) ->
int {
110 Require (opaqueStream == stream);
111 [[maybe_unused]] MyZipLibInStream_* myThis =
reinterpret_cast<MyZipLibInStream_*
> (opaqueStream);
112#if qStroika_Foundation_Debug_AssertionsChecked
113 Assert (myThis->fOpened_);
119 ~MyZipLibInStream_ ()
121#if qStroika_Foundation_Debug_AssertionsChecked
122 Assert (not fOpened_);
130 struct Rep_ final :
public Reader::IRep {
131 MyZipLibInStream_ fInSeekStream_;
136 , fZipFile_{unzOpen2_64 (
"", &fInSeekStream_)}
138 if (fZipFile_ ==
nullptr) [[unlikely]] {
146 unzClose (fZipFile_);
148 virtual Set<String> GetContainedFiles ()
const override
151 unz_global_info64 gi;
152 ThrowIfMinizipErr_ (unzGetGlobalInfo64 (fZipFile_, &gi),
"unzGetGlobalInfo64"sv);
153 for (
size_t i = 0; i < gi.number_entry; i++) {
154 char filename_inzip[10 * 1024];
155 unz_file_info64 file_info;
159 ThrowIfMinizipErr_ (::unzGetCurrentFileInfo64 (fZipFile_, &file_info, filename_inzip,
sizeof (filename_inzip), NULL, 0, NULL, 0),
160 "unzGetGlobalInfo64"sv);
161 if ((i + 1) < gi.number_entry) {
162 ThrowIfMinizipErr_ (::unzGoToNextFile_ (fZipFile_),
"unzGoToNextFile_"sv);
165 if (filename_inzip[::strlen (filename_inzip) - 1] ==
'/') {
169 result.
Add (String::FromUTF8 (filename_inzip));
174 unz_global_info64 gi;
177 err = unzGetGlobalInfo64(uf, &gi);
179 printf(
"error %d with zipfile in unzGetGlobalInfo \n", err);
180 printf(
" Length Method Size Ratio Date Time CRC-32 Name\n");
181 printf(
" ------ ------ ---- ----- ---- ---- ------ ----\n");
182 for (i = 0; i < gi.number_entry; ++i) {
183 char filename_inzip[256];
184 unz_file_info64 file_info;
186 const char* string_method;
187 char charCrypt =
' ';
188 err = unzGetCurrentFileInfo64(uf, &file_info, filename_inzip,
sizeof(filename_inzip), NULL, 0, NULL, 0);
190 printf(
"error %d with zipfile in unzGetCurrentFileInfo\n", err);
193 if (file_info.uncompressed_size > 0)
194 ratio = (uLong)((file_info.compressed_size * 100) / file_info.uncompressed_size);
197 if ((file_info.flag & 1) != 0)
200 if (file_info.compression_method == 0)
201 string_method =
"Stored";
202 else if (file_info.compression_method == Z_DEFLATED) {
203 uInt iLevel = (uInt)((file_info.flag & 0x6) / 2);
205 string_method =
"Defl:N";
206 else if (iLevel == 1)
207 string_method =
"Defl:X";
208 else if ((iLevel == 2) or (iLevel == 3))
209 string_method =
"Defl:F";
211 else if (file_info.compression_method == Z_BZIP2ED) {
212 string_method =
"BZip2 ";
215 string_method =
"Unkn. ";
217 Display64BitsSize(file_info.uncompressed_size, 7);
218 printf(
" %6s%c", string_method, charCrypt);
219 Display64BitsSize(file_info.compressed_size, 7);
220 printf(
" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
222 (uLong)file_info.tmu_date.tm_mon + 1,
223 (uLong)file_info.tmu_date.tm_mday,
224 (uLong)file_info.tmu_date.tm_year % 100,
225 (uLong)file_info.tmu_date.tm_hour, (uLong)file_info.tmu_date.tm_min,
226 (uLong)file_info.crc, filename_inzip);
227 if ((i + 1) < gi.number_entry) {
228 err = unzGoToNextFile_ (uf);
230 printf(
"error %d with zipfile in unzGoToNextFile\n", err);
236 for (
unsigned int i = 0; i < fDB_.NumFiles; i++) {
237 if (not SzArEx_IsDir (&fDB_, i)) {
238 size_t nameLen = ::SzArEx_GetFileNameUtf16 (&fDB_, i,
nullptr);
243 size_t z = ::SzArEx_GetFileNameUtf16 (&fDB_, i,
reinterpret_cast<UInt16*
> (&fileName[0]));
253 if (unzLocateFile_ (fZipFile_, fileName.
AsUTF8<
string> ().c_str (), 1) != UNZ_OK) [[unlikely]] {
256 const char* password =
nullptr;
257 int err = unzOpenCurrentFilePassword (fZipFile_, password);
258 [[maybe_unused]]
auto&& cleanup =
Finally ([
this] ()
noexcept { unzCloseCurrentFile_ (fZipFile_); });
262 err = unzReadCurrentFile_ (fZipFile_, buf,
static_cast<unsigned int> (Memory::NEltsOf (buf)));
263 if (err < 0) [[unlikely]] {
267 Assert (
static_cast<size_t> (err) <= Memory::NEltsOf (buf));
268 tmpBuf.Write (span{buf,
static_cast<size_t> (err)});
283 return Archive::Reader::Ptr{make_shared<Rep_> (readFrom)};
#define RequireNotReached()
#define AssertNotReached()
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual T AsUTF8() const
Set<T> is a container of T, where once an item is added, additionally adds () do nothing.
nonvirtual void Add(ArgByValueType< value_type > item)
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
auto Finally(FUNCTION &&f) -> Private_::FinallySentry< FUNCTION >