4#include "Stroika/Foundation/StroikaPreComp.h"
11#if qStroika_HasComponent_LZMA
14#include <lzma/7zCrc.h>
18#if qStroika_HasComponent_LZMA && defined(_MSC_VER)
20#pragma comment(lib, "lzma.lib")
27using namespace Stroika::Foundation::DataExchange::Archive;
28using namespace Stroika::Foundation::Streams;
33#if qStroika_HasComponent_LZMA
38 ::CrcGenerateTable ();
45 struct Rep_ : Reader::IRep {
48 static void* Alloc_ (
void* ,
size_t size)
51 return new byte[size];
53 static void Free_ (
void* ,
void* address)
55 delete[]
reinterpret_cast<byte*
> (address);
59 mutable ISzAlloc fAllocImp_{};
60 mutable ISzAlloc fAllocTempImp_{};
62 struct MyISeekInStream : ISeekInStream {
70 static SRes Stream_Read_ (
void* pp,
void* buf,
size_t* size)
72 MyISeekInStream* pThis = (MyISeekInStream*)pp;
73 size_t sz = pThis->fInStream_.ReadBlocking (span{
reinterpret_cast<byte*
> (buf), *size}).size ();
78 static SRes Stream_Seek_ (
void* pp, Int64* pos, ESzSeek origin)
80 MyISeekInStream* pThis = (MyISeekInStream*)pp;
83 *pos = pThis->fInStream_.Seek (*pos);
86 *pos = pThis->fInStream_.Seek (eFromCurrent, *pos);
89 *pos = pThis->fInStream_.Seek (eFromEnd, *pos);
93 return SZ_ERROR_UNSUPPORTED;
98 MyISeekInStream fInSeekStream_;
99 mutable CLookToRead fLookStream_{};
105 fAllocImp_ = ISzAlloc{Alloc_, Free_};
106 fAllocTempImp_ = ISzAlloc{Alloc_, Free_};
108 ::SzArEx_Init (&fDB_);
110 ::LookToRead_CreateVTable (&fLookStream_,
false);
111 fLookStream_.realStream = &fInSeekStream_;
114 if ((ret = ::SzArEx_Open (&fDB_, &fLookStream_.s, &fAllocImp_, &fAllocTempImp_)) != SZ_OK) {
121 ::SzArEx_Free (&fDB_, &fAllocImp_);
123 virtual Set<String> GetContainedFiles ()
const override
126 for (
unsigned int i = 0; i < fDB_.NumFiles; ++i) {
127 if (not SzArEx_IsDir (&fDB_, i)) {
128 size_t nameLen = ::SzArEx_GetFileNameUtf16 (&fDB_, i,
nullptr);
132 StackBuffer<char16_t> fileName{Memory::eUninitialized, nameLen};
133 [[maybe_unused]]
size_t z = ::SzArEx_GetFileNameUtf16 (&fDB_, i,
reinterpret_cast<UInt16*
> (&fileName[0]));
141 UInt32 idx = GetIdx_ (fileName);
147 UInt32 blockIndex = 0xFFFFFFFF;
148 size_t outBufferSize = 0;
151 size_t outSizeProcessed{};
153 [[maybe_unused]]
auto&& cleanup = Execution::Finally ([&outBuffer,
this] ()
noexcept { IAlloc_Free (&fAllocImp_, outBuffer); });
156 if ((ret = ::SzArEx_Extract (&fDB_, &fLookStream_.s, idx, &blockIndex,
reinterpret_cast<uint8_t**
> (&outBuffer), &outBufferSize,
157 &offset, &outSizeProcessed, &fAllocImp_, &fAllocTempImp_)) != SZ_OK) {
160 return Memory::BLOB (outBuffer + offset, outBuffer + offset + outSizeProcessed);
162 UInt32 GetIdx_ (
const String& fn)
const
165 for (UInt32 i = 0; i < fDB_.NumFiles; ++i) {
166 if (not SzArEx_IsDir (&fDB_, i)) {
167 size_t nameLen = SzArEx_GetFileNameUtf16 (&fDB_, i,
nullptr);
171 StackBuffer<char16_t> fileName{Memory::eUninitialized, nameLen};
172 [[maybe_unused]]
size_t z = ::SzArEx_GetFileNameUtf16 (&fDB_, i,
reinterpret_cast<UInt16*
> (&fileName[0]));
173 if (
String{&fileName[0]} == fn) {
178 return static_cast<UInt32
> (-1);
190 return Archive::Reader::Ptr{make_shared<Rep_> (readFrom)};
#define AssertNotReached()
String is like std::u32string, except it is much easier to use, often much more space efficient,...
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...