!88 删除miniz仓依赖(挑单:runtime_core部分)

Merge pull request !88 from 董开兴/lts_3.0_cherypick
This commit is contained in:
openharmony_ci
2022-03-21 12:00:40 +00:00
committed by Gitee
9 changed files with 902 additions and 1457 deletions
+4 -1
View File
@@ -23,7 +23,10 @@ config("arkfile_public_config") {
]
if (!ark_standalone_build) {
include_dirs += [ "//third_party/miniz/amalgamation" ]
include_dirs += [
"//third_party/zlib",
"//third_party/zlib/contrib/minizip",
]
} else {
include_dirs += [ "$ark_third_party_root/miniz" ]
}
+100 -157
View File
@@ -46,13 +46,10 @@ constexpr int EOK = 0;
#endif // EOK
// NOLINTNEXTLINE(readability-identifier-naming, modernize-avoid-c-arrays)
const char *ARCHIVE_FILENAME = "classes.aex";
const char *ARCHIVE_FILENAME = "classes.abc";
// NOLINTNEXTLINE(readability-identifier-naming, modernize-avoid-c-arrays)
const char *ARCHIVE_SPLIT = "!/";
// NOLINTNEXTLINE(readability-identifier-naming, modernize-avoid-c-arrays)
const char *ARCHIVE_FILENAME_ABC = "classes.abc";
const std::array<uint8_t, File::MAGIC_SIZE> File::MAGIC {'P', 'A', 'N', 'D', 'A', '\0', '\0', '\0'};
// Name anonymous maps for perfing tools finding symbol file correctly.
@@ -108,38 +105,77 @@ std::unique_ptr<const File> OpenPandaFileOrZip(std::string_view location, panda_
return OpenPandaFile(location, archive_filename, open_mode);
}
std::unique_ptr<const panda_file::File> HandleArchive(FILE *fp, std::string_view location,
std::string_view archive_filename,
panda_file::File::OpenMode open_mode)
// NOLINTNEXTLINE(google-runtime-references)
void OpenPandaFileFromZipErrorHandler(ZipArchiveHandle &handle)
{
EntryFileStat entry = EntryFileStat();
std::string archive_fn = std::string(archive_filename);
if (!archive_fn.empty()) {
if (!GetArchiveFileEntry(fp, archive_fn.c_str(), &entry)) {
LOG(ERROR, PANDAFILE) << "Can't find entry with name '" << archive_fn << "'";
return nullptr;
}
} else {
if (!GetArchiveFileEntry(fp, ARCHIVE_FILENAME, &entry)) {
if (!GetArchiveFileEntry(fp, ARCHIVE_FILENAME_ABC, &entry)) {
LOG(ERROR, PANDAFILE) << "Can't find entry with name '" << ARCHIVE_FILENAME << "' or '"
<< ARCHIVE_FILENAME_ABC << "'";
return nullptr;
}
if (handle != nullptr) {
if (panda::CloseArchiveFile(handle) != ZIPARCHIVE_OK) {
LOG(ERROR, PANDAFILE) << "CloseArchiveFile failed!";
}
}
}
std::unique_ptr<const panda_file::File> OpenPandaFileFromZipFile(ZipArchiveHandle &handle, std::string_view location,
EntryFileStat &entry, std::string_view archive_name)
{
uint32_t uncompressed_length = entry.GetUncompressedSize();
if (uncompressed_length == 0) {
CloseCurrentFile(handle);
OpenPandaFileFromZipErrorHandler(handle);
LOG(ERROR, PANDAFILE) << "Panda file has zero length!";
return nullptr;
}
size_t size_to_mmap = AlignUp(uncompressed_length, panda::os::mem::GetPageSize());
void *mem = os::mem::MapRWAnonymousRaw(size_to_mmap, false);
if (mem == nullptr) {
CloseCurrentFile(handle);
OpenPandaFileFromZipErrorHandler(handle);
LOG(ERROR, PANDAFILE) << "Can't mmap anonymous!";
return nullptr;
}
os::mem::BytePtr ptr(reinterpret_cast<std::byte *>(mem), size_to_mmap, os::mem::MmapDeleter);
std::stringstream ss;
ss << ANONMAPNAME_PERFIX << archive_name << " extracted in memory from " << location;
auto it = AnonMemSet::GetInstance().Insert(std::string(location), ss.str());
auto ret = os::mem::TagAnonymousMemory(reinterpret_cast<void *>(ptr.Get()), size_to_mmap, it->second.c_str());
if (ret.has_value()) {
CloseCurrentFile(handle);
OpenPandaFileFromZipErrorHandler(handle);
LOG(ERROR, PANDAFILE) << "Can't tag mmap anonymous!";
return nullptr;
}
auto extract_error = ExtractToMemory(handle, reinterpret_cast<uint8_t *>(ptr.Get()), size_to_mmap);
if (extract_error != 0) {
CloseCurrentFile(handle);
OpenPandaFileFromZipErrorHandler(handle);
LOG(ERROR, PANDAFILE) << "Can't extract!";
return nullptr;
}
os::mem::ConstBytePtr ConstPtr = ptr.ToConst();
return panda_file::File::OpenFromMemory(std::move(ConstPtr), location);
}
// NOLINTNEXTLINE(google-runtime-references)
std::unique_ptr<const panda_file::File> HandleArchive(ZipArchiveHandle &handle, FILE *fp, std::string_view location,
EntryFileStat &entry, std::string_view archive_filename,
panda_file::File::OpenMode open_mode)
{
std::unique_ptr<const panda_file::File> file;
// compressed or not 4 aligned, use anonymous memory
if (entry.IsCompressed() || (entry.GetOffset() & 0x3U) != 0) {
file = OpenPandaFileFromZipFILE(fp, location, archive_filename);
file = OpenPandaFileFromZipFile(handle, location, entry, archive_filename);
} else {
LOG(INFO, PANDAFILE) << "Pandafile is uncompressed and 4 bytes aligned";
file = panda_file::File::OpenUncompressedArchive(fileno(fp), location, entry.GetUncompressedSize(),
entry.GetOffset(), open_mode);
}
return file;
}
// CODECHECK-NOLINTNEXTLINE(C_RULE_ID_FUNCTION_SIZE)
std::unique_ptr<const panda_file::File> OpenPandaFile(std::string_view location, std::string_view archive_filename,
panda_file::File::OpenMode open_mode)
{
@@ -166,7 +202,48 @@ std::unique_ptr<const panda_file::File> OpenPandaFile(std::string_view location,
fseek(fp, 0, SEEK_SET);
std::unique_ptr<const panda_file::File> file;
if (IsZipMagic(magic)) {
file = HandleArchive(fp, location, archive_filename, open_mode);
// Open Zipfile and do the extraction.
ZipArchiveHandle zipfile = nullptr;
auto open_error = OpenArchiveFile(zipfile, fp);
if (open_error != ZIPARCHIVE_OK) {
LOG(ERROR, PANDAFILE) << "Can't open archive " << location;
return nullptr;
}
bool try_default = archive_filename.empty();
if (!try_default) {
if (LocateFile(zipfile, archive_filename.data()) != ZIPARCHIVE_OK) {
LOG(INFO, PANDAFILE) << "Can't find entry with name '" << archive_filename << "', will try "
<< ARCHIVE_FILENAME;
try_default = true;
}
}
if (try_default) {
if (LocateFile(zipfile, ARCHIVE_FILENAME) != ZIPARCHIVE_OK) {
OpenPandaFileFromZipErrorHandler(zipfile);
LOG(ERROR, PANDAFILE) << "Can't find entry with " << ARCHIVE_FILENAME;
fclose(fp);
return nullptr;
}
}
EntryFileStat entry = EntryFileStat();
if (GetCurrentFileInfo(zipfile, &entry) != ZIPARCHIVE_OK) {
OpenPandaFileFromZipErrorHandler(zipfile);
LOG(ERROR, PANDAFILE) << "GetCurrentFileInfo error";
return nullptr;
}
if (OpenCurrentFile(zipfile) != ZIPARCHIVE_OK) {
CloseCurrentFile(zipfile);
OpenPandaFileFromZipErrorHandler(zipfile);
LOG(ERROR, PANDAFILE) << "Can't OpenCurrentFile!";
return nullptr;
}
GetCurrentFileOffset(zipfile, &entry);
file = HandleArchive(zipfile, fp, location, entry, archive_filename, open_mode);
CloseCurrentFile(zipfile);
if (panda::CloseArchiveFile(zipfile) != 0) {
LOG(ERROR, PANDAFILE) << "CloseArchive failed!";
return nullptr;
}
} else {
file = panda_file::File::Open(location, open_mode);
}
@@ -174,143 +251,9 @@ std::unique_ptr<const panda_file::File> OpenPandaFile(std::string_view location,
return file;
}
// NOLINTNEXTLINE(google-runtime-references)
void OpenPandaFileFromZipErrorHandler(ZipArchiveHandle &handle, const char *message)
{
if (handle != nullptr) {
if (!panda::CloseArchive(&handle)) {
LOG(ERROR, PANDAFILE) << "CloseArchive failed!";
}
}
LOG(ERROR, PANDAFILE) << message;
}
std::unique_ptr<const panda_file::File> OpenPandaFileFromZip(std::string_view location)
{
trace::ScopedTrace scoped_trace("Panda file open Zip " + std::string(location));
panda::ZipArchive archive_holder;
panda::ZipArchiveHandle handle = &archive_holder;
auto open_error = panda::OpenArchive(std::string(location).c_str(), &handle);
if (open_error != 0) {
LOG(ERROR, PANDAFILE) << "Can't open archive\n";
return nullptr;
}
auto entry = std::make_unique<EntryFileStat>();
const char *filename = ARCHIVE_FILENAME;
if (panda::FindEntry(&handle, entry.get(), filename) != 0) {
filename = ARCHIVE_FILENAME_ABC;
auto find_error = panda::FindEntry(&handle, entry.get(), filename);
if (find_error != 0) {
OpenPandaFileFromZipErrorHandler(handle, "Can't find entry!");
return nullptr;
}
}
uint32_t uncompressed_length = entry->GetUncompressedSize();
if (entry->GetUncompressedSize() == 0) {
OpenPandaFileFromZipErrorHandler(handle, "Panda file has zero length!");
return nullptr;
}
size_t size_to_mmap = AlignUp(uncompressed_length, panda::os::mem::GetPageSize());
// NB! This mem is mapped in OpenPandaFileFromZip, we want to use it otherwhere, better unposion it!
void *mem = os::mem::MapRWAnonymousRaw(size_to_mmap, false);
if (mem == nullptr) {
OpenPandaFileFromZipErrorHandler(handle, "Can't mmap anonymous!");
return nullptr;
}
std::stringstream ss;
ss << ANONMAPNAME_PERFIX << ARCHIVE_FILENAME << " extracted in memory from " << location;
auto it = AnonMemSet::GetInstance().Insert(std::string(location), ss.str());
auto ret = os::mem::TagAnonymousMemory(mem, size_to_mmap, it->second.c_str());
if (ret.has_value()) {
return nullptr;
}
auto extract_error = panda::ExtractToMemory(&handle, entry.get(), reinterpret_cast<uint8_t *>(mem), size_to_mmap);
if (extract_error != 0) {
os::mem::UnmapRaw(mem, size_to_mmap);
OpenPandaFileFromZipErrorHandler(handle, "Can't extract!");
return nullptr;
}
if (!panda::CloseArchive(&handle)) {
LOG(ERROR, PANDAFILE) << "CloseArchive failed!";
return nullptr;
}
os::mem::ConstBytePtr ptr(reinterpret_cast<std::byte *>(mem), size_to_mmap, os::mem::MmapDeleter);
return panda_file::File::OpenFromMemory(std::move(ptr), location);
}
std::unique_ptr<const panda_file::File> OpenPandaFileFromZipFILE(FILE *inputfile, std::string_view location,
std::string_view archive_filename)
{
panda::ZipArchive archive_holder;
panda::ZipArchiveHandle handle = &archive_holder;
auto open_error = panda::OpenArchiveFILE(inputfile, &handle);
if (open_error != 0) {
LOG(ERROR, PANDAFILE) << "Can't open archive\n";
return nullptr;
}
auto entry = std::make_unique<EntryFileStat>();
std::string archive_fn = std::string(archive_filename);
const char *filename = archive_fn.empty() ? ARCHIVE_FILENAME : archive_fn.c_str();
if (panda::FindEntry(&handle, entry.get(), filename) != 0) {
filename = ARCHIVE_FILENAME_ABC;
auto find_error = panda::FindEntry(&handle, entry.get(), filename);
if (find_error != 0) {
OpenPandaFileFromZipErrorHandler(handle, "Can't find entry!");
return nullptr;
}
}
uint32_t uncompressed_length = entry->GetUncompressedSize();
if (entry->GetUncompressedSize() == 0) {
OpenPandaFileFromZipErrorHandler(handle, "Panda file has zero length!");
return nullptr;
}
size_t size_to_mmap = AlignUp(uncompressed_length, panda::os::mem::GetPageSize());
// NB! This mem is mapped in OpenPandaFileFromZip, we want to use it otherwhere, better unposion it!
void *mem = os::mem::MapRWAnonymousRaw(size_to_mmap, false);
if (mem == nullptr) {
OpenPandaFileFromZipErrorHandler(handle, "Can't mmap anonymous!");
return nullptr;
}
std::stringstream ss;
ss << ANONMAPNAME_PERFIX << ARCHIVE_FILENAME << " extracted in memory from " << location;
auto it = AnonMemSet::GetInstance().Insert(std::string(location), ss.str());
auto ret = os::mem::TagAnonymousMemory(mem, size_to_mmap, it->second.c_str());
if (ret.has_value()) {
OpenPandaFileFromZipErrorHandler(handle, "Can't tag mmap anonymous!");
return nullptr;
}
auto extract_error = panda::ExtractToMemory(&handle, entry.get(), reinterpret_cast<uint8_t *>(mem), size_to_mmap);
if (extract_error != 0) {
os::mem::UnmapRaw(mem, size_to_mmap);
OpenPandaFileFromZipErrorHandler(handle, "Can't extract!");
return nullptr;
}
if (!panda::CloseArchive(&handle)) {
LOG(ERROR, PANDAFILE) << "CloseArchive failed!";
return nullptr;
}
os::mem::ConstBytePtr ptr(reinterpret_cast<std::byte *>(mem), size_to_mmap, os::mem::MmapDeleter);
return panda_file::File::OpenFromMemory(std::move(ptr), location);
}
std::unique_ptr<const File> OpenPandaFileFromMemory(const void *buffer, size_t size)
{
size_t size_to_mmap = AlignUp(size, panda::os::mem::GetPageSize());
// NB! This mem is mapped in OpenPandaFileFromZip, we want to use it otherwhere, better unposion it!
void *mem = os::mem::MapRWAnonymousRaw(size_to_mmap, false);
if (mem == nullptr) {
return nullptr;
+4 -22
View File
@@ -28,6 +28,10 @@
#include <string>
#include <string_view>
namespace panda {
struct EntryFileStat;
} // namespace panda
namespace panda::panda_file {
class PandaCache;
@@ -350,24 +354,6 @@ std::unique_ptr<const File> OpenPandaFileFromMemory(const void *buffer, size_t s
std::unique_ptr<const File> OpenPandaFile(std::string_view location, std::string_view archive_filename = "",
panda_file::File::OpenMode open_mode = panda_file::File::READ_ONLY);
/*
* OpenPandaFileFromZip from location which specicify the name.
*/
std::unique_ptr<const panda_file::File> OpenPandaFileFromZip(std::string_view location);
/*
* Open Archive file.
*/
std::unique_ptr<const panda_file::File> HandleArchive(
FILE *fp, std::string_view location, std::string_view archive_filename = "",
panda_file::File::OpenMode open_mode = panda_file::File::READ_ONLY);
/*
* OpenPandaFileFromZip from FILE* inputfile
*/
std::unique_ptr<const panda_file::File> OpenPandaFileFromZipFILE(FILE *inputfile, std::string_view location,
std::string_view archive_filename);
/*
* Check ptr point valid panda file: magic
*/
@@ -375,10 +361,6 @@ bool CheckHeader(const os::mem::ConstBytePtr &ptr, const std::string_view &filen
// NOLINTNEXTLINE(readability-identifier-naming)
extern const char *ARCHIVE_FILENAME;
// NOLINTNEXTLINE(readability-identifier-naming)
extern const char *ARCHIVE_FILENAME_ABC;
} // namespace panda::panda_file
#endif // PANDA_LIBPANDAFILE_FILE_H_
+1 -1
View File
@@ -14,7 +14,7 @@
*/
#include "file_writer.h"
#include "miniz.h"
#include "zlib.h"
namespace panda::panda_file {
+73 -55
View File
@@ -63,14 +63,15 @@ static std::vector<uint8_t> GetEmptyPandaFileBytes()
return data;
}
int CreateOrAddZipPandaFile(std::vector<uint8_t> *data, const char *zip_archive_name, const char *filename)
int CreateOrAddZipPandaFile(std::vector<uint8_t> *data, const char *zip_archive_name, const char *filename, int append,
int level)
{
return CreateOrAddFileIntoZip(zip_archive_name, filename, (*data).data(), (*data).size());
return CreateOrAddFileIntoZip(zip_archive_name, filename, (*data).data(), (*data).size(), append, level);
}
bool CheckAnonMemoryName([[maybe_unused]] const char *zip_archive_name)
{
// check if [annon:panda-classes.aex extracted in memory from /xx/__OpenPandaFileFromZip__.zip]
// check if [annon:panda-classes.abc extracted in memory from /xx/__OpenPandaFileFromZip__.zip]
#ifdef PANDA_TARGET_MOBILE
bool result = false;
const char *prefix = "[anon:panda-";
@@ -135,65 +136,82 @@ TEST(File, GetClassByName)
}
}
TEST(File, OpenPandaFileFromZip)
TEST(File, OpenPandaFile)
{
{
// Create ZIP
auto data = GetEmptyPandaFileBytes();
int ret;
const char *zip_filename = "__OpenPandaFileFromZip__.zip";
const char *filename1 = ARCHIVE_FILENAME;
const char *filename2 = "classses2.aex"; // just for testing.
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename1);
ASSERT_EQ(ret, 0);
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename2);
ASSERT_EQ(ret, 0);
// Create ZIP
auto data = GetEmptyPandaFileBytes();
int ret;
const char *zip_filename = "__OpenPandaFile__.zip";
const char *filename1 = ARCHIVE_FILENAME;
const char *filename2 = "classses2.abc"; // just for testing.
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename1, APPEND_STATUS_CREATE, Z_BEST_COMPRESSION);
ASSERT_EQ(ret, 0);
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename2, APPEND_STATUS_ADDINZIP, Z_BEST_COMPRESSION);
ASSERT_EQ(ret, 0);
// Open from ZIP
auto pf = OpenPandaFile(zip_filename);
EXPECT_NE(pf, nullptr);
EXPECT_STREQ((pf->GetFilename()).c_str(), zip_filename);
}
}
TEST(File, OpenPandaFileABCFromZip)
{
{
// Create ZIP
auto data = GetEmptyPandaFileBytes();
int ret;
const char *zip_filename = "__OpenPandaFileABCFromZip__.zip";
const char *filename1 = ARCHIVE_FILENAME_ABC;
const char *filename2 = "classses2.aex"; // just for testing.
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename1);
ASSERT_EQ(ret, 0);
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename2);
ASSERT_EQ(ret, 0);
// Open from ZIP
auto pf = OpenPandaFile(zip_filename);
EXPECT_NE(pf, nullptr);
EXPECT_STREQ((pf->GetFilename()).c_str(), zip_filename);
}
// Open from ZIP
auto pf = OpenPandaFile(zip_filename);
EXPECT_NE(pf, nullptr);
EXPECT_STREQ((pf->GetFilename()).c_str(), zip_filename);
remove(zip_filename);
}
TEST(File, OpenPandaFileFromZipNameAnonMem)
{
{
// Create ZIP
auto data = GetEmptyPandaFileBytes();
int ret;
const char *zip_filename = "__OpenPandaFileFromZip__.zip";
const char *filename1 = ARCHIVE_FILENAME;
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename1);
ASSERT_EQ(ret, 0);
// Create ZIP
auto data = GetEmptyPandaFileBytes();
int ret;
const char *zip_filename = "__OpenPandaFileFromZipNameAnonMem__.zip";
const char *filename1 = ARCHIVE_FILENAME;
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename1, APPEND_STATUS_CREATE, Z_BEST_COMPRESSION);
ASSERT_EQ(ret, 0);
// Open from ZIP
auto pf = OpenPandaFile(zip_filename);
EXPECT_NE(pf, nullptr);
EXPECT_STREQ((pf->GetFilename()).c_str(), zip_filename);
ASSERT_TRUE(CheckAnonMemoryName(zip_filename));
}
// Open from ZIP
auto pf = OpenPandaFile(zip_filename);
EXPECT_NE(pf, nullptr);
EXPECT_STREQ((pf->GetFilename()).c_str(), zip_filename);
ASSERT_TRUE(CheckAnonMemoryName(zip_filename));
remove(zip_filename);
}
TEST(File, OpenPandaFileOrZip)
{
// Create ZIP
auto data = GetEmptyPandaFileBytes();
int ret;
const char *zip_filename = "__OpenPandaFileOrZip__.zip";
const char *filename1 = ARCHIVE_FILENAME;
const char *filename2 = "classes2.abc"; // just for testing.
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename1, APPEND_STATUS_CREATE, Z_BEST_COMPRESSION);
ASSERT_EQ(ret, 0);
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename2, APPEND_STATUS_ADDINZIP, Z_BEST_COMPRESSION);
ASSERT_EQ(ret, 0);
// Open from ZIP
auto pf = OpenPandaFileOrZip(zip_filename);
EXPECT_NE(pf, nullptr);
EXPECT_STREQ((pf->GetFilename()).c_str(), zip_filename);
remove(zip_filename);
}
TEST(File, OpenPandaFileUncompressed)
{
// Create ZIP
auto data = GetEmptyPandaFileBytes();
std::cout << "pandafile size = " << data.size() << std::endl;
int ret;
const char *zip_filename = "__OpenPandaFileUncompressed__.zip";
const char *filename1 = ARCHIVE_FILENAME;
const char *filename2 = "class.abc"; // just for testing.
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename2, APPEND_STATUS_CREATE, Z_NO_COMPRESSION);
ASSERT_EQ(ret, 0);
ret = CreateOrAddZipPandaFile(&data, zip_filename, filename1, APPEND_STATUS_ADDINZIP, Z_NO_COMPRESSION);
ASSERT_EQ(ret, 0);
// Open from ZIP
auto pf = OpenPandaFileOrZip(zip_filename);
EXPECT_NE(pf, nullptr);
EXPECT_STREQ((pf->GetFilename()).c_str(), zip_filename);
remove(zip_filename);
}
} // namespace panda::panda_file::test
+6 -3
View File
@@ -21,7 +21,10 @@ config("arkziparchive_config") {
]
if (!ark_standalone_build) {
include_dirs += [ "//third_party/miniz/amalgamation" ]
include_dirs += [
"//third_party/zlib",
"//third_party/zlib/contrib/minizip",
]
} else {
include_dirs += [ "$ark_third_party_root/miniz" ]
}
@@ -42,7 +45,7 @@ ohos_shared_library("libarkziparchive") {
]
if (!ark_standalone_build) {
deps += [ "//third_party/miniz/amalgamation:libminiz" ]
deps += [ "//third_party/zlib:libz" ]
} else {
deps += [ "$ark_third_party_root/miniz:libminiz" ]
}
@@ -68,7 +71,7 @@ ohos_static_library("libarkziparchive_frontend_static") {
]
if (!ark_standalone_build) {
deps += [ "//third_party/miniz/amalgamation:libminiz" ]
deps += [ "//third_party/zlib:libz" ]
} else {
deps += [ "$ark_third_party_root/miniz:libminiz" ]
}
File diff suppressed because it is too large Load Diff
+101 -147
View File
@@ -18,11 +18,6 @@
#include "utils/logger.h"
#include <securec.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream>
#include <cstdio>
#include <memory>
namespace panda {
@@ -34,200 +29,159 @@ bool IsZipMagic(uint32_t magic)
return (('P' == ((magic >> 0U) & ZIP_MAGIC_MASK)) && ('K' == ((magic >> ZIP_MAGIC_OFFSET) & ZIP_MAGIC_MASK)));
}
int32_t OpenArchive(const char *zip_filename, ZipArchiveHandle *handle)
int OpenArchive(ZipArchiveHandle &handle, const char *path)
{
if (handle == nullptr || memset_s(*handle, sizeof(ZipArchive), 0, sizeof(ZipArchive)) != EOK) {
LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
return -1;
handle = unzOpen(path);
if (handle == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "OpenArchive failed, filename is " << path;
return ZIPARCHIVE_ERR;
}
if (mz_zip_reader_init_file(*handle, zip_filename, 0) == 0) {
LOG(ERROR, ZIPARCHIVE) << "mz_zip_reader_init_file() failed!";
return -1;
}
return 0;
return ZIPARCHIVE_OK;
}
int32_t OpenArchiveFILE(FILE *fp, ZipArchiveHandle *handle)
int OpenArchiveFile(ZipArchiveHandle &handle, FILE *fp)
{
if (handle == nullptr || memset_s(*handle, sizeof(ZipArchive), 0, sizeof(ZipArchive)) != EOK) {
LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
return -1;
handle = unzOpenFile(fp);
if (handle == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "OpenArchive failed from FILE *fp";
return ZIPARCHIVE_ERR;
}
auto file = std::make_unique<os::file::File>(fileno(fp));
if (file == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "Failed to get get file\n";
return -1;
}
auto res = file->GetFileSize();
if (!res) {
LOG(ERROR, ZIPARCHIVE) << "Failed to get size of panda file\n";
return -1;
}
size_t file_size = res.Value();
if (mz_zip_reader_init_cfile(*handle, fp, file_size, 0) == 0) {
LOG(ERROR, ZIPARCHIVE) << "mz_zip_reader_init_cfile() failed!\n";
return -1;
}
return 0;
return ZIPARCHIVE_OK;
}
bool CloseArchive(ZipArchiveHandle *handle)
int CloseArchive(ZipArchiveHandle &handle)
{
if (handle == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
return false;
return ZIPARCHIVE_ERR;
}
return mz_zip_reader_end(*handle) != 0;
int err = unzClose(handle);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "unzClose with error: " << err;
return ZIPARCHIVE_ERR;
}
return ZIPARCHIVE_OK;
}
int32_t FindEntry(ZipArchiveHandle *handle, EntryFileStat *entry, const char *entryname, const char *pcomment)
int CloseArchiveFile(ZipArchiveHandle &handle)
{
if (handle == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
return -1;
return ZIPARCHIVE_ERR;
}
int32_t index = LocateFileIndex(handle, entryname, pcomment);
if (index == -1) {
LOG(INFO, ZIPARCHIVE) << "LocateFileIndex() failed!";
return -1;
int err = unzCloseFile(handle);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "unzCloseFile with error: " << err;
return ZIPARCHIVE_ERR;
}
if (!StatFileWithIndex(handle, entry, static_cast<unsigned int>(index))) {
LOG(INFO, ZIPARCHIVE) << "StatFileWithIndex() failed!";
return -1;
}
return 0;
return ZIPARCHIVE_OK;
}
int32_t GetFileCount(ZipArchiveHandle *handle)
int GetGlobalFileInfo(ZipArchiveHandle &handle, GlobalStat *gstat)
{
if (handle == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
return -1;
int err = unzGetGlobalInfo(handle, &gstat->ginfo);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "GetGlobalFileInfo with error: " << err;
return ZIPARCHIVE_ERR;
}
return static_cast<int>(mz_zip_reader_get_num_files(*handle));
return ZIPARCHIVE_OK;
}
int32_t LocateFileIndex(ZipArchiveHandle *handle, const char *filename, const char *comment)
int GoToNextFile(ZipArchiveHandle &handle)
{
if (handle == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
return -1;
int err = unzGoToNextFile(handle);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "GoToNextFile with error: " << err;
return ZIPARCHIVE_ERR;
}
return static_cast<int32_t>(mz_zip_reader_locate_file(*handle, filename, comment, MZ_ZIP_FLAG_CASE_SENSITIVE));
return ZIPARCHIVE_OK;
}
bool StatFileWithIndex(ZipArchiveHandle *handle, EntryFileStat *entry, unsigned int index)
int LocateFile(ZipArchiveHandle &handle, const char *filename)
{
if (handle == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
return false;
int err = unzLocateFile2(handle, filename, 0);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << filename << " is not found in the zipfile";
return ZIPARCHIVE_ERR;
}
if (mz_zip_reader_file_stat(*handle, index, &(entry->file_stat)) == 0) {
LOG(ERROR, ZIPARCHIVE) << "mz_zip_reader_file_stat() failed!";
return false;
}
if (mz_zip_reader_file_ofs(*handle, &(entry->file_stat), &(entry->offset)) == 0) {
LOG(ERROR, ZIPARCHIVE) << "mz_zip_reader_file_offset() failed!";
return false;
}
return true;
return ZIPARCHIVE_OK;
}
bool IsFileDirectory(ZipArchiveHandle *handle, unsigned int index)
int GetCurrentFileInfo(ZipArchiveHandle &handle, EntryFileStat *entry)
{
if (handle == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
return false;
int err = unzGetCurrentFileInfo(handle, &entry->file_stat, nullptr, 0, nullptr, 0, nullptr, 0);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "unzGetCurrentFileInfo failed!";
return ZIPARCHIVE_ERR;
}
return mz_zip_reader_is_file_a_directory(*handle, index) != 0;
return ZIPARCHIVE_OK;
}
int32_t ExtractToMemory(ZipArchiveHandle *handle, EntryFileStat *entry, void *buf, size_t buf_size)
int OpenCurrentFile(ZipArchiveHandle &handle)
{
if (handle == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
return -1;
int err = unzOpenCurrentFile(handle);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "OpenCurrentFile failed!";
return ZIPARCHIVE_ERR;
}
if (mz_zip_reader_extract_to_mem(*handle, entry->GetIndex(), buf, buf_size, 0) == 0) {
LOG(ERROR, ZIPARCHIVE) << "mz_zip_reader_extract_to_mem() failed!\n";
return -1;
}
return 0;
return ZIPARCHIVE_OK;
}
void *ExtractToHeap(ZipArchiveHandle *handle, const char *filename, size_t *puncomp_size)
void GetCurrentFileOffset(ZipArchiveHandle &handle, EntryFileStat *entry)
{
if (handle == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "ZipArchiveHandle handle should not be nullptr";
return nullptr;
}
void *heap_buf = mz_zip_reader_extract_file_to_heap(*handle, filename, puncomp_size, 0);
if (heap_buf == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "mz_zip_reader_extract_file_to_heap() failed!\n";
return nullptr;
}
return heap_buf;
entry->offset = static_cast<uint32_t>(unzGetCurrentFileZStreamPos64(handle));
}
void FreeHeap(void *heapbuf)
int CloseCurrentFile(ZipArchiveHandle &handle)
{
mz_free(heapbuf);
int err = unzCloseCurrentFile(handle);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "CloseCurrentFile failed!";
return ZIPARCHIVE_ERR;
}
return ZIPARCHIVE_OK;
}
int32_t CreateOrAddFileIntoZip(const char *zip_filename, const char *filename, const void *pbuf, size_t buf_size,
const void *pcomment, mz_uint16 comment_size)
int ExtractToMemory(ZipArchiveHandle &handle, void *buf, size_t buf_size)
{
if (mz_zip_add_mem_to_archive_file_in_place(zip_filename, filename, pbuf, buf_size, pcomment, comment_size,
MZ_BEST_COMPRESSION) == 0) {
LOG(ERROR, ZIPARCHIVE) << "mz_zip_add_mem_to_archive_file_in_place failed!\n";
return -1;
int size = unzReadCurrentFile(handle, buf, buf_size);
if (size < 0) {
LOG(ERROR, ZIPARCHIVE) << "ExtractToMemory failed!";
return ZIPARCHIVE_ERR;
}
return 0;
LOG(INFO, ZIPARCHIVE) << "ExtractToMemory size is " << size;
return ZIPARCHIVE_OK;
}
int32_t CreateOrAddUncompressedFileIntoZip(const char *zip_filename, const char *filename, const void *pbuf,
size_t buf_size, const void *pcomment, mz_uint16 comment_size)
int CreateOrAddFileIntoZip(const char *zipname, const char *filename, const void *pbuf, size_t buf_size, int append,
int level)
{
if (mz_zip_add_mem_to_archive_file_in_place(zip_filename, filename, pbuf, buf_size, pcomment, comment_size,
MZ_NO_COMPRESSION) == 0) {
LOG(ERROR, ZIPARCHIVE) << "mz_zip_add_mem_to_archive_file_in_place failed!\n";
return -1;
zipFile zfile = nullptr;
zfile = zipOpen(zipname, append);
if (zfile == nullptr) {
LOG(ERROR, ZIPARCHIVE) << "CreateArchive failed, zipname is " << zipname;
return ZIPARCHIVE_ERR;
}
return 0;
int success = ZIPARCHIVE_OK;
int err = zipOpenNewFileInZip(zfile, filename, nullptr, nullptr, 0, nullptr, 0, nullptr,
(level != 0) ? Z_DEFLATED : 0, level);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "zipOpenNewFileInZip failed!, zipname is" << zipname << ", filename is " << filename;
return ZIPARCHIVE_ERR;
}
err = zipWriteInFileInZip(zfile, pbuf, buf_size);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "zipWriteInFileInZip failed!, zipname is" << zipname << ", filename is " << filename;
success = ZIPARCHIVE_ERR;
}
err = zipCloseFileInZip(zfile);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "zipCloseFileInZip failed!, zipname is" << zipname << ", filename is " << filename;
}
err = zipClose(zfile, nullptr);
if (err != UNZ_OK) {
LOG(ERROR, ZIPARCHIVE) << "CloseArcive failed!, zipname is" << zipname;
}
return success;
}
bool GetArchiveFileEntry(FILE *inputfile, const char *archive_filename, EntryFileStat *entry)
{
panda::ZipArchive archive_holder;
panda::ZipArchiveHandle handle = &archive_holder;
fseek(inputfile, 0, SEEK_SET);
auto open_error = panda::OpenArchiveFILE(inputfile, &handle);
if (open_error != 0) {
LOG(ERROR, ZIPARCHIVE) << "Can't open archive\n";
return false;
}
auto find_error = panda::FindEntry(&handle, entry, archive_filename);
if (!panda::CloseArchive(&handle)) {
LOG(ERROR, ZIPARCHIVE) << "CloseArchive failed!";
return false;
}
fseek(inputfile, 0, SEEK_SET);
if (find_error != 0) {
LOG(INFO, ZIPARCHIVE) << "Can't find entry with name '" << archive_filename << "'";
return false;
}
return true;
}
} // namespace panda
+87 -87
View File
@@ -16,38 +16,27 @@
#ifndef PANDA_LIBZIPARCHIVE_ZIP_ARCHIVE_H_
#define PANDA_LIBZIPARCHIVE_ZIP_ARCHIVE_H_
#include "miniz.h"
#include <cstdint>
#include "unzip.h"
#include "zip.h"
namespace panda {
using ZipArchive = mz_zip_archive;
using ZipArchiveHandle = mz_zip_archive *;
constexpr int ZIPARCHIVE_OK = 0;
constexpr int ZIPARCHIVE_ERR = 1;
using ZipArchiveHandle = unzFile;
struct EntryFileStat {
public:
const char *GetFileName() const
{
return file_stat.m_filename;
}
const char *GetComment() const
{
return file_stat.m_comment;
}
uint32_t GetUncompressedSize() const
{
return (uint32_t)file_stat.m_uncomp_size;
return (uint32_t)file_stat.uncompressed_size;
}
uint32_t GetCompressedSize() const
{
return (uint32_t)file_stat.m_comp_size;
}
uint32_t GetIndex() const
{
return file_stat.m_file_index;
return (uint32_t)file_stat.compressed_size;
}
inline uint32_t GetOffset() const
@@ -55,116 +44,127 @@ public:
return offset;
}
inline bool IsCompressed()
inline bool IsCompressed() const
{
return mz_zip_reader_file_is_compressed(&file_stat);
return file_stat.compression_method != 0;
}
mz_zip_archive_file_stat file_stat;
unz_file_info file_stat;
uint32_t offset;
};
struct GlobalStat {
public:
uint32_t GetNumberOfEntry() const
{
return (uint32_t)ginfo.number_entry;
}
unz_global_info ginfo;
};
/*
* Judge whether magic is zip magic.
*/
bool IsZipMagic(uint32_t magic);
/*
* Open a Zip archive, and set handle for the file.
* Open a Zip archive from filename path, and sets handle for the file.
* This handle must be released by calling CloseArchive with this handle.
* CloseArchive will close the file zip_filename opened.
* CloseArchive will close the file opened.
*
* Returns 0 on success, and -1 on failure.
* Returns 0 on success, and 1 on failure.
*/
int32_t OpenArchive(const char *zip_filename, ZipArchiveHandle *handle);
int OpenArchive(ZipArchiveHandle &handle, const char *path);
/*
* Open a Zip archive FILE, and set handle for the file.
* This handle must be released by calling CloseArchive with this handle.
* CloseArchive will not close the fp. It is the caller's responsibility.
* Close archive opened with OpenArchive, releasing internal resources associated with it.
*/
int CloseArchive(ZipArchiveHandle &handle);
/*
* Open a Zip archive from opened file FILE* fp, and sets handle for the file.
* This handle must be released by calling CloseArchiveFile with this handle.
* CloseArchiveFile will not close the fp. It is the caller's responsibility.
*
* Returns 0 on success, and -1 on failure.
* Returns 0 on success, and 1 on failure.
*/
int32_t OpenArchiveFILE(FILE *fp, ZipArchiveHandle *handle);
int OpenArchiveFile(ZipArchiveHandle &handle, FILE *fp);
/*
* Close archive, releasing internal resources associated with it.
*/
bool CloseArchive(ZipArchiveHandle *handle);
/*
* Find an entry in the Zip archive by entryname as well as comment name.
* comment name defaultly is nullptr.
* Close archive opened with OpenArchiveFile, releasing internal resources associated with it.
*
* stat must point to a writeable memory location (e.g. new/malloc).
* Returns 0 on success, and 1 on failure.
*/
int CloseArchiveFile(ZipArchiveHandle &handle);
/*
* Write the info about the ZipFile into *gstat structure.
*
* Return 0 if an entry is found, and populate stat with information about this entry,
* Return -1 otherwise.
* Returns 0 on success, and 1 on failure.
*/
int32_t FindEntry(ZipArchiveHandle *handle, EntryFileStat *entry, const char *entryname,
const char *pcomment = nullptr);
int GetGlobalFileInfo(ZipArchiveHandle &handle, GlobalStat *gstat);
/*
* Return the total number of files in the archive.
* Set the current file of the zipfile to the next file.
*
* Returns 0 on success, and 1 on failure.
*/
int32_t GetFileCount(ZipArchiveHandle *handle);
int GoToNextFile(ZipArchiveHandle &handle);
/*
* Attempt to locate a file in the archive's central directory.
* Return the index if file be found, otherwise -1.
* Try locate the file filename in the zipfile.
*
* Returns 0 on success, and 1 on failure.
*/
int32_t LocateFileIndex(ZipArchiveHandle *handle, const char *filename, const char *comment = nullptr);
int LocateFile(ZipArchiveHandle &handle, const char *filename);
/*
* Return detailed information about an archive file entry according to index.
* Get Info about the current file within ZipFile and write info into the *entry structure.
* No preparation of the structure is needed
*
* Returns 0 on success, and 1 on failure.
*/
bool StatFileWithIndex(ZipArchiveHandle *handle, EntryFileStat *entry, unsigned int index);
int GetCurrentFileInfo(ZipArchiveHandle &handle, EntryFileStat *entry);
/*
* Return true if the archive file entry index is a directory, otherwise false
* Open for reading data the current file in the zipfile.
* This handle must be released by calling CloseCurrentFile with this handle.
*
* Returns 0 on success, and 1 on failure.
*/
bool IsFileDirectory(ZipArchiveHandle *handle, unsigned int index);
int OpenCurrentFile(ZipArchiveHandle &handle);
/*
* Uncompress a given zip entry to the memory buf of size |buf_size|.
* Get the current file offset opened with OpenCurrentFile. The offset will be stored into entry->offset.
*/
void GetCurrentFileOffset(ZipArchiveHandle &handle, EntryFileStat *entry);
/*
* Close the file in zip opened with unzOpenCurrentFile
*
* Returns 0 on success, and 1 on failure.
*/
int CloseCurrentFile(ZipArchiveHandle &handle);
/*
* Uncompress a given zip archive represented with handle to buf of size |buf_size|.
* This size is expected to be equal or larger than the uncompressed length of the zip entry.
* Returns 0 on success and -1 on failure.
*
* Returns 0 on success and 1 on failure.
*/
int32_t ExtractToMemory(ZipArchiveHandle *handle, EntryFileStat *entry, void *buf, size_t buf_size);
int ExtractToMemory(ZipArchiveHandle &handle, void *buf, size_t buf_size);
/*
* Uncompress a given filename in zip to heap memory.
* The corresponding uncompressed_size is returned in puncomp_size by pointer.
* Returns the heap address on success and nullptr on failure.
* Add a new file filename(resident in memory pbuf which has size of size |buf_size|) to the archive zipname,
* append takes value from APPEND_STATUS_CREATE(which will create the archive zipname for first time) and
* APPEND_STATUS_ADDINZIP(which willappend filename into exsisted zip archive zipname).
* level takes value from Z_BEST_COMPRESSION(which will deflate the pbuf with best compression effect) and
* Z_NO_COMPRESSION(which will store the pbuf into zipname without compression).
*
* Returns 0 on success and 1 on failure.
*/
void *ExtractToHeap(ZipArchiveHandle *handle, const char *filename, size_t *puncomp_size);
/*
* Release a block allocated from the heap.
*/
void FreeHeap(void *heapbuf);
/*
* Add a new file (in memory) to the archive. Note this is an IN-PLACE operation,
* so if it fails your archive is probably hosed (its central directory may not be complete) but it should be
* recoverable using zip -F or -FF. So use this with caution.
*/
int32_t CreateOrAddFileIntoZip(const char *zip_filename, const char *filename, const void *pbuf, size_t buf_size,
const void *pcomment = nullptr, mz_uint16 comment_size = 0);
/*
* Add a new file (in memory) to the archive without compression. Note this is an IN-PLACE operation,
* so if it fails your archive is probably hosed (its central directory may not be complete) but it should be
* recoverable using zip -F or -FF. So use this with caution.
*/
int32_t CreateOrAddUncompressedFileIntoZip(const char *zip_filename, const char *filename, const void *pbuf,
size_t buf_size, const void *pcomment, mz_uint16 comment_size);
/*
* GetArchiveFileEntry from FILE* inputfile
*/
bool GetArchiveFileEntry(FILE *inputfile, const char *archive_filename, EntryFileStat *entry);
int CreateOrAddFileIntoZip(const char *zipname, const char *filename, const void *pbuf, size_t buf_size,
int append = APPEND_STATUS_CREATE, int level = Z_BEST_COMPRESSION);
} // namespace panda
#endif // PANDA_LIBZIPARCHIVE_ZIP_ARCHIVE_H_