4#include "Stroika/Foundation/StroikaPreComp.h"
12#if qStroika_HasComponent_LZMA
15#include <lzma/7zCrc.h>
23using namespace Stroika::Foundation::DataExchange::Archive;
24using namespace Stroika::Foundation::Streams;
29#if qStroika_HasComponent_LZMA
34 ::CrcGenerateTable ();
41 struct Rep_ : Reader::IRep {
44 static void* Alloc_ (
void* ,
size_t size)
47 return new byte[size];
49 static void Free_ (
void* ,
void* address)
51 delete[]
reinterpret_cast<byte*
> (address);
55 mutable ISzAlloc fAllocImp_{};
56 mutable ISzAlloc fAllocTempImp_{};
58 struct MyISeekInStream : ISeekInStream {
66 static SRes Stream_Read_ (
void* pp,
void* buf,
size_t* size)
68 MyISeekInStream* pThis = (MyISeekInStream*)pp;
69 size_t sz = pThis->fInStream_.ReadBlocking (span{
reinterpret_cast<byte*
> (buf), *size}).size ();
74 static SRes Stream_Seek_ (
void* pp, Int64* pos, ESzSeek origin)
76 MyISeekInStream* pThis = (MyISeekInStream*)pp;
79 *pos = pThis->fInStream_.Seek (*pos);
82 *pos = pThis->fInStream_.Seek (eFromCurrent, *pos);
85 *pos = pThis->fInStream_.Seek (eFromEnd, *pos);
89 return SZ_ERROR_UNSUPPORTED;
94 MyISeekInStream fInSeekStream_;
95 mutable CLookToRead fLookStream_{};
101 fAllocImp_ = ISzAlloc{Alloc_, Free_};
102 fAllocTempImp_ = ISzAlloc{Alloc_, Free_};
104 ::SzArEx_Init (&fDB_);
106 ::LookToRead_CreateVTable (&fLookStream_,
false);
107 fLookStream_.realStream = &fInSeekStream_;
110 if ((ret = ::SzArEx_Open (&fDB_, &fLookStream_.s, &fAllocImp_, &fAllocTempImp_)) != SZ_OK) {
117 ::SzArEx_Free (&fDB_, &fAllocImp_);
119 virtual Set<String> GetContainedFiles ()
const override
122 for (
unsigned int i = 0; i < fDB_.NumFiles; ++i) {
123 if (not SzArEx_IsDir (&fDB_, i)) {
124 size_t nameLen = ::SzArEx_GetFileNameUtf16 (&fDB_, i,
nullptr);
128 StackBuffer<char16_t> fileName{Memory::eUninitialized, nameLen};
129 [[maybe_unused]]
size_t z = ::SzArEx_GetFileNameUtf16 (&fDB_, i,
reinterpret_cast<UInt16*
> (&fileName[0]));
137 UInt32 idx = GetIdx_ (fileName);
143 UInt32 blockIndex = 0xFFFFFFFF;
144 size_t outBufferSize = 0;
147 size_t outSizeProcessed{};
149 [[maybe_unused]]
auto&& cleanup = Execution::Finally ([&outBuffer,
this] ()
noexcept { IAlloc_Free (&fAllocImp_, outBuffer); });
152 if ((ret = ::SzArEx_Extract (&fDB_, &fLookStream_.s, idx, &blockIndex,
reinterpret_cast<uint8_t**
> (&outBuffer), &outBufferSize,
153 &offset, &outSizeProcessed, &fAllocImp_, &fAllocTempImp_)) != SZ_OK) {
156 return Memory::BLOB (outBuffer + offset, outBuffer + offset + outSizeProcessed);
158 UInt32 GetIdx_ (
const String& fn)
const
161 for (UInt32 i = 0; i < fDB_.NumFiles; ++i) {
162 if (not SzArEx_IsDir (&fDB_, i)) {
163 size_t nameLen = SzArEx_GetFileNameUtf16 (&fDB_, i,
nullptr);
167 StackBuffer<char16_t> fileName{Memory::eUninitialized, nameLen};
168 [[maybe_unused]]
size_t z = ::SzArEx_GetFileNameUtf16 (&fDB_, i,
reinterpret_cast<UInt16*
> (&fileName[0]));
169 if (
String{&fileName[0]} == fn) {
174 return static_cast<UInt32
> (-1);
186 return Archive::Reader::Ptr{Memory::MakeSharedPtr<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...