diff --git a/InMemoryArchive.h b/InMemoryArchive.h index d960dab..b4bf64a 100644 --- a/InMemoryArchive.h +++ b/InMemoryArchive.h @@ -10,4 +10,5 @@ class InMemoryArchive { InMemoryArchive(); InMemoryFileSystem FileSystem; + std::u8string Password; }; \ No newline at end of file diff --git a/InMemoryArchiveUpdateCallback.cpp b/InMemoryArchiveUpdateCallback.cpp index e4d69d9..7d2cf92 100644 --- a/InMemoryArchiveUpdateCallback.cpp +++ b/InMemoryArchiveUpdateCallback.cpp @@ -24,7 +24,7 @@ InMemoryArchiveUpdateCallback::~InMemoryArchiveUpdateCallback() fmt::print("Cleanup InMemoryArchiveUpdateCallback"); } -InMemoryArchiveUpdateCallback::InMemoryArchiveUpdateCallback(InMemoryArchive* Archive) : Archive(Archive) //, Password(u8"1234") +InMemoryArchiveUpdateCallback::InMemoryArchiveUpdateCallback(InMemoryArchive* Archive) : Archive(Archive) {} Z7_COM7F_IMF(InMemoryArchiveUpdateCallback::SetTotal(UInt64 size)) @@ -157,12 +157,13 @@ Z7_COM7F_IMF(InMemoryArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISeque Z7_COM7F_IMF(InMemoryArchiveUpdateCallback::CryptoGetTextPassword2(Int32* passwordIsDefined, BSTR* password)) { fmt::print("InMemoryArchiveUpdateCallback::CryptoGetTextPassword2()\n"); - if (!Password.empty()) + const bool PasswordIsDefined = !Archive->Password.empty(); + if (PasswordIsDefined && password != nullptr) { - const auto PasswordW = boost::nowide::widen(Password); + const auto PasswordW = boost::nowide::widen(Archive->Password); *password = ::SysAllocStringLen(PasswordW.c_str(), PasswordW.size()); - *passwordIsDefined = 1; } - *passwordIsDefined = 0; + if (passwordIsDefined) + *passwordIsDefined = PasswordIsDefined; return S_OK; } \ No newline at end of file diff --git a/InMemoryArchiveUpdateCallback.h b/InMemoryArchiveUpdateCallback.h index 4ad4231..3c3d279 100644 --- a/InMemoryArchiveUpdateCallback.h +++ b/InMemoryArchiveUpdateCallback.h @@ -26,5 +26,4 @@ class InMemoryArchiveUpdateCallback Z7_final : private: InMemoryArchive* Archive{}; - std::u8string Password; }; diff --git a/InMemoryOutStream.cpp b/InMemoryOutStream.cpp index 9ba000c..f10a030 100644 --- a/InMemoryOutStream.cpp +++ b/InMemoryOutStream.cpp @@ -1,30 +1,38 @@ #include "InMemoryOutStream.h" +#include #include #include -InMemoryOutStream::InMemoryOutStream(std::vector& Data): Data(&Data) +InMemoryOutStream::InMemoryOutStream(std::vector& Data) : Data(&Data) {} InMemoryOutStream::~InMemoryOutStream() = default; -Z7_COM7F_IMF(InMemoryOutStream::Write(const void* data, UInt32 size, UInt32* processedSize)) +static std::size_t writeBytesToBuffer(auto& Buffer, std::size_t Position, std::span BytesToWrite) { - const auto BytesToWrite = static_cast(size); - const auto OverWriteBytes = std::min(Data->size() - Position, BytesToWrite); - std::memcpy(Data->data() + Position, data, OverWriteBytes); - fmt::print("InMemoryOutStream::Write overwrite {} of {} bytes of current buffer of size {}.\n", OverWriteBytes, BytesToWrite, Data->size()); - Position += OverWriteBytes; - - const auto RemainingBytes = BytesToWrite - OverWriteBytes; - if (RemainingBytes != 0) + const auto BytesToOverwrite = BytesToWrite.subspan(0, std::min(std::ranges::size(Buffer) - Position, BytesToWrite.size())); + const auto BytesToAppend = BytesToWrite.subspan(BytesToOverwrite.size()); + fmt::print("InMemoryOutStream::Write overwrite {} of {} bytes of current buffer of size {}.\n", BytesToOverwrite.size(), BytesToWrite.size(), std::ranges::size(Buffer)); + const auto CurrentPositionIterator = std::ranges::copy(BytesToOverwrite, std::ranges::next(std::ranges::begin(Buffer), Position)).out; + if (!BytesToAppend.empty()) { - const auto RemainingBytesView = std::span{ static_cast(data) + OverWriteBytes, RemainingBytes }; - Data->insert(Data->end(), RemainingBytesView.begin(), RemainingBytesView.end()); - fmt::print("InMemoryOutStream::Write append remaining {} of {} bytes of current buffer of size {}.\n", RemainingBytes, BytesToWrite, Data->size()); - Position = Data->size(); + assert(CurrentPositionIterator == std::ranges::end(Buffer)); + fmt::print("InMemoryOutStream::Write append remaining {} of {} bytes of current buffer of size {}.\n", BytesToAppend.size(), BytesToWrite.size(), std::ranges::size(Buffer)); + std::ranges::copy(BytesToAppend, std::back_inserter(Buffer)); + return std::ranges::size(Buffer); } + const auto NewPosition = std::ranges::distance(std::ranges::begin(Buffer), CurrentPositionIterator); + fmt::print("InMemoryOutStream::Write move position from {} to {}.\n", Position, NewPosition); + return NewPosition; +} + + +Z7_COM7F_IMF(InMemoryOutStream::Write(const void* data, UInt32 size, UInt32* processedSize)) +{ + const auto BytesToWrite = std::span{ static_cast(data), static_cast(size) }; + Position = ::writeBytesToBuffer(*Data, Position, BytesToWrite); if (processedSize) *processedSize = size; return S_OK; diff --git a/InMemoryOutStream.h b/InMemoryOutStream.h index 94ee751..e588d8c 100644 --- a/InMemoryOutStream.h +++ b/InMemoryOutStream.h @@ -20,5 +20,5 @@ class InMemoryOutStream Z7_final : private: std::vector* Data; - size_t Position{}; + std::size_t Position{}; }; \ No newline at end of file diff --git a/main.cpp b/main.cpp index a14bbf2..e019aa0 100644 --- a/main.cpp +++ b/main.cpp @@ -22,8 +22,8 @@ size_t getUncompressedSizeOfFile(IInArchive* Archive, UInt32 Index) Archive->GetProperty(Index, kpidSize, &prop); if (prop.vt == VT_UI8) return prop.uhVal.QuadPart; - - throw std::runtime_error(""); + + throw std::runtime_error(""); } std::string getFileName(IInArchive* Archive, UInt32 Index) @@ -34,7 +34,7 @@ std::string getFileName(IInArchive* Archive, UInt32 Index) return boost::nowide::narrow(prop.bstrVal); else if (prop.vt != VT_EMPTY) return std::to_string(prop.vt); - return {}; + return {}; } @@ -44,7 +44,7 @@ void extractStuff(ArchiveFactory& Factory) CMyComPtr Archive = Factory.createIInArchive(); CMyComPtr OpenCallback(new InMemoryArchiveOpenCallback(u8"Password")); - CMyComPtr InMemoryInStreamCallback (new StdFileInStream(TestArchive)); + CMyComPtr InMemoryInStreamCallback(new StdFileInStream(TestArchive)); const UInt64 scanSize = 1 << 23; if (const auto OpenResult = Archive->Open(InMemoryInStreamCallback, &scanSize, OpenCallback); OpenResult != S_OK) @@ -73,16 +73,17 @@ void compressStuff(ArchiveFactory& Factory) { CMyComPtr OutArchive = Factory.createIOutArchive(); InMemoryArchive TempArchive; - unsigned char FileContent[] = "ASCII"; - const std::span FileContentView{ (std::byte*)FileContent, std::size(FileContent)-1 }; + TempArchive.Password = u8"Password"; + unsigned char FileContent[] = "ASCII and stuff"; + const std::span FileContentView{ (std::byte*)FileContent, std::size(FileContent) - 1 }; TempArchive.FileSystem.createFile(u8"SomeFile.txt", FileContentView); auto UpdateCallback = TempArchive.getUpdateCallback(); std::vector Buffer; - CMyComPtr InMemoryOutStreamInstance (new InMemoryOutStream(Buffer)); + CMyComPtr InMemoryOutStreamInstance(new InMemoryOutStream(Buffer)); OutArchive->UpdateItems(InMemoryOutStreamInstance, 1, UpdateCallback); - std::ofstream OutFile("generatedArchive.7z",std::ios_base::trunc| std::ios_base::binary); + std::ofstream OutFile("generatedArchive.7z", std::ios_base::trunc | std::ios_base::binary); OutFile.write((const char*)Buffer.data(), Buffer.size()); }