This commit is contained in:
jeanlemotan
2024-07-02 18:12:23 +02:00
commit b344afa9fe
89 changed files with 10568 additions and 0 deletions
+90
View File
@@ -0,0 +1,90 @@
#include "StdAfx.h"
#include "fs/IFilesystem.h"
#include "fs/zip/ZipUtils.h"
#include "fs/zip/ZipPack.h"
#include "fs/WritableFolderPack.h"
#include "fs/CopyStream.h"
#include "fs/zip/ZipWriter.h"
#include "fs/zip/DeflateFileWriter.h"
namespace fs
{
namespace
{
UnzipResult unzip(IFilesystem& dstFilesystem, const AbsPath& filePath, tl::unique_ref<ZipPack> zipPack)
{
MakeFolderResult makeFolderResult = dstFilesystem.makeFolder(filePath);
if (makeFolderResult.has_error())
return makeFolderResult.error();
for (const EnumerateEntry& ee: zipPack->enumerateRecursively(AbsPath("/")))
{
AbsPath dstPath = filePath + ee.path;
OUTCOME_TRY(dstFilesystem.makeFolder(ee.isFolder ? dstPath : dstPath.parent()));
if (!ee.isFolder)
{
OUTCOME_TRY(auto source, zipPack->openStreamSource(AbsPath("/") + ee.path));
OUTCOME_TRY(auto sink, dstFilesystem.openStreamSink(dstPath, Mode::CreateOrOpenAndClear));
OUTCOME_TRY(copyStream(*sink, *source));
}
}
return tl::success();
}
}
UnzipResult unzipSource(IFilesystem& dstFilesystem, const AbsPath& filePath, tl::unique_ref<IMapSource> source)
{
OUTCOME_TRY(auto pack, ZipPack::create(std::move(source)));
return unzip(dstFilesystem, filePath, std::move(pack));
}
UnzipResult unzipFile(IFilesystem& dstFilesystem, const AbsPath& filePath, tl::lent_ref<const IFilesystem> filesystem, AbsPath srcFilePath)
{
OUTCOME_TRY(auto pack, ZipPack::create(std::move(filesystem), std::move(srcFilePath)));
return unzip(dstFilesystem, filePath, std::move(pack));
}
ZipResult zipToSink(ISink& sink, tl::lent_ref<IFilesystem> filesystem, const AbsPath& path, uint8_t compressionLevel, size_t fileDataAlignment)
{
ZipWriter writer(sink, fileDataAlignment);
OUTCOME_TRY(const bool isFile, filesystem->isFile(path));
if (isFile)
{
tl::result<void> addResult = writer.addFile(path.str(), [&filesystem, &path, compressionLevel](IStreamSink& sink)
{
return DeflateFileWriter(path, filesystem, compressionLevel)(sink);
});
if (addResult.has_error())
return tl::make_error<Error>(ErrorCode::SystemError, "Cannot add file '{}' zip: {}", path, addResult.error());
}
else
{
for (EnumerateEntry ee: filesystem->enumerateRecursively(path))
{
if (!ee.isFolder)
{
tl::result<void> addResult = writer.addFile(ee.path.get_as<PosixSystem>(), [&filesystem, &path, &ee, compressionLevel](IStreamSink& sink)
{
return DeflateFileWriter(path + ee.path, filesystem, compressionLevel)(sink);
});
if (addResult.has_error())
return {tl::make_error<Error>(ErrorCode::SystemError, "Cannot add file '{}' zip: {}", path + ee.path, addResult.error())};
}
}
}
writer.finish();
return tl::success();
}
ZipResult zipToFile(IFilesystem& dstFilesystem, const AbsPath& dstFilePath, tl::lent_ref<IFilesystem> filesystem, const AbsPath& path, uint8_t compressionLevel, size_t fileDataAlignment)
{
OUTCOME_TRY(const auto sink, dstFilesystem.openSink(dstFilePath, Mode::CreateOrOpenAndClear));
return zipToSink(*sink, std::move(filesystem), path, compressionLevel, fileDataAlignment);
}
}