cleanup
This commit is contained in:
parent
b52cc1aea0
commit
7facc33a7e
@ -81,19 +81,19 @@ ZipFileDevice::Entry ZipFileDevice::readEntry() {
|
|||||||
read_int(file, entry.crc32);
|
read_int(file, entry.crc32);
|
||||||
read_int(file, entry.compressedSize);
|
read_int(file, entry.compressedSize);
|
||||||
read_int(file, entry.uncompressedSize);
|
read_int(file, entry.uncompressedSize);
|
||||||
auto fileNameLength = read_int<uint16_t>(file);
|
auto filename_len = read_int<uint16_t>(file);
|
||||||
auto extraFieldLength = read_int<uint16_t>(file);
|
auto extra_field_len = read_int<uint16_t>(file);
|
||||||
auto fileCommentLength = read_int<uint16_t>(file);
|
auto file_comment_len = read_int<uint16_t>(file);
|
||||||
read_int(file, entry.diskNumberStart);
|
read_int(file, entry.diskNumberStart);
|
||||||
read_int(file, entry.internalAttributes);
|
read_int(file, entry.internalAttributes);
|
||||||
read_int(file, entry.externalAttributes);
|
read_int(file, entry.externalAttributes);
|
||||||
read_int(file, entry.localHeaderOffset);
|
read_int(file, entry.localHeaderOffset);
|
||||||
|
|
||||||
entry.fileName.resize(fileNameLength, '\0');
|
entry.fileName.resize(filename_len, '\0');
|
||||||
file->read(entry.fileName.data(), fileNameLength);
|
file->read(entry.fileName.data(), filename_len);
|
||||||
|
|
||||||
// Skip extra field and file comment
|
// Skip extra field and file comment
|
||||||
file->seekg(extraFieldLength + fileCommentLength, std::ios::cur);
|
file->seekg(extra_field_len + file_comment_len, std::ios::cur);
|
||||||
|
|
||||||
if (entry.diskNumberStart == 0xFF) {
|
if (entry.diskNumberStart == 0xFF) {
|
||||||
throw std::runtime_error("zip64 is not supported");
|
throw std::runtime_error("zip64 is not supported");
|
||||||
@ -124,11 +124,11 @@ void ZipFileDevice::findBlob(Entry& entry) {
|
|||||||
read_int<uint32_t>(file); // crc32
|
read_int<uint32_t>(file); // crc32
|
||||||
read_int<uint32_t>(file); // compressed size
|
read_int<uint32_t>(file); // compressed size
|
||||||
read_int<uint32_t>(file); // uncompressed size
|
read_int<uint32_t>(file); // uncompressed size
|
||||||
auto nameLength = read_int<uint16_t>(file);
|
auto name_len = read_int<uint16_t>(file);
|
||||||
auto extraFieldLength = read_int<uint16_t>(file);
|
auto extra_field_len = read_int<uint16_t>(file);
|
||||||
|
|
||||||
// Skip extra field and file comment
|
// Skip extra field and file comment
|
||||||
file->seekg(nameLength + extraFieldLength, std::ios::cur);
|
file->seekg(name_len + extra_field_len, std::ios::cur);
|
||||||
entry.blobOffset = file->tellg();
|
entry.blobOffset = file->tellg();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,10 +138,10 @@ ZipFileDevice::ZipFileDevice(
|
|||||||
: file(std::move(filePtr)), separateFunc(std::move(separateFunc)) {
|
: file(std::move(filePtr)), separateFunc(std::move(separateFunc)) {
|
||||||
// Searching for EOCD
|
// Searching for EOCD
|
||||||
file->seekg(0, std::ios::end);
|
file->seekg(0, std::ios::end);
|
||||||
std::streampos fileSize = file->tellg();
|
std::streampos file_size = file->tellg();
|
||||||
|
|
||||||
bool foundEOCD = false;
|
bool foundEOCD = false;
|
||||||
for (int pos = static_cast<int>(fileSize)-4; pos >= 0; --pos) {
|
for (int pos = static_cast<int>(file_size)-4; pos >= 0; --pos) {
|
||||||
file->seekg(pos);
|
file->seekg(pos);
|
||||||
if (read_int<uint32_t>(file) == EOCD_SIGNATURE) {
|
if (read_int<uint32_t>(file) == EOCD_SIGNATURE) {
|
||||||
foundEOCD = true;
|
foundEOCD = true;
|
||||||
@ -156,14 +156,14 @@ ZipFileDevice::ZipFileDevice(
|
|||||||
read_int<uint16_t>(file); // diskNumber
|
read_int<uint16_t>(file); // diskNumber
|
||||||
read_int<uint16_t>(file); // centralDirDisk
|
read_int<uint16_t>(file); // centralDirDisk
|
||||||
read_int<uint16_t>(file); // numEntriesThisDisk
|
read_int<uint16_t>(file); // numEntriesThisDisk
|
||||||
auto totalEntries = read_int<uint16_t>(file);
|
auto total_entries = read_int<uint16_t>(file);
|
||||||
read_int<uint32_t>(file); // centralDirSize
|
read_int<uint32_t>(file); // centralDirSize
|
||||||
auto centralDirOffset = read_int<uint32_t>(file);
|
auto central_dir_offset = read_int<uint32_t>(file);
|
||||||
read_int<uint16_t>(file); // commentLength
|
read_int<uint16_t>(file); // commentLength
|
||||||
|
|
||||||
file->seekg(centralDirOffset);
|
file->seekg(central_dir_offset);
|
||||||
|
|
||||||
for (uint16_t i = 0; i < totalEntries; i++) {
|
for (uint16_t i = 0; i < total_entries; i++) {
|
||||||
if (read_int<uint32_t>(file) != CENTRAL_DIR_SIGNATURE) {
|
if (read_int<uint32_t>(file) != CENTRAL_DIR_SIGNATURE) {
|
||||||
logger.error() << "invalid central directory entry";
|
logger.error() << "invalid central directory entry";
|
||||||
break;
|
break;
|
||||||
@ -198,22 +198,22 @@ std::unique_ptr<std::istream> ZipFileDevice::read(std::string_view path) {
|
|||||||
if (entry.blobOffset == 0) {
|
if (entry.blobOffset == 0) {
|
||||||
findBlob(entry);
|
findBlob(entry);
|
||||||
}
|
}
|
||||||
std::unique_ptr<std::istream> srcStream;
|
std::unique_ptr<std::istream> src_stream;
|
||||||
if (separateFunc) {
|
if (separateFunc) {
|
||||||
// Create new istream for concurrent data reading
|
// Create new istream for concurrent data reading
|
||||||
srcStream = separateFunc();
|
src_stream = separateFunc();
|
||||||
srcStream->seekg(entry.blobOffset);
|
src_stream->seekg(entry.blobOffset);
|
||||||
} else {
|
} else {
|
||||||
// Read compressed data to memory if istream cannot be separated
|
// Read compressed data to memory if istream cannot be separated
|
||||||
file->seekg(entry.blobOffset);
|
file->seekg(entry.blobOffset);
|
||||||
util::Buffer<char> buffer(entry.compressedSize);
|
util::Buffer<char> buffer(entry.compressedSize);
|
||||||
file->read(buffer.data(), buffer.size());
|
file->read(buffer.data(), buffer.size());
|
||||||
srcStream = std::make_unique<memory_istream>(std::move(buffer));
|
src_stream = std::make_unique<memory_istream>(std::move(buffer));
|
||||||
}
|
}
|
||||||
if (entry.compressionMethod == COMPRESSION_NONE) {
|
if (entry.compressionMethod == COMPRESSION_NONE) {
|
||||||
return srcStream;
|
return src_stream;
|
||||||
} else if (entry.compressionMethod == COMPRESSION_DEFLATE) {
|
} else if (entry.compressionMethod == COMPRESSION_DEFLATE) {
|
||||||
return std::make_unique<deflate_istream>(std::move(srcStream));
|
return std::make_unique<deflate_istream>(std::move(src_stream));
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"unsupported compression method [" +
|
"unsupported compression method [" +
|
||||||
@ -301,17 +301,17 @@ std::unique_ptr<PathsGenerator> ZipFileDevice::list(std::string_view path) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto folder = std::string(path) + "/";
|
auto folder = std::string(path) + "/";
|
||||||
size_t folderLen = folder.length();
|
size_t folder_len = folder.length();
|
||||||
for (const auto& [name, entry] : entries) {
|
for (const auto& [name, entry] : entries) {
|
||||||
if (name.find(folder) != 0) {
|
if (name.find(folder) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
size_t pos = name.find('/', folderLen);
|
size_t pos = name.find('/', folder_len);
|
||||||
if (pos == std::string::npos) {
|
if (pos == std::string::npos) {
|
||||||
names.push_back(name.substr(folderLen, pos - folderLen));
|
names.push_back(name.substr(folder_len, pos - folder_len));
|
||||||
}
|
}
|
||||||
if (pos == name.length() - 1) {
|
if (pos == name.length() - 1) {
|
||||||
names.push_back(name.substr(folderLen, pos - folderLen));
|
names.push_back(name.substr(folder_len, pos - folder_len));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,60 +324,59 @@ std::unique_ptr<PathsGenerator> ZipFileDevice::list(std::string_view path) {
|
|||||||
static void write_headers(
|
static void write_headers(
|
||||||
std::ostream& file,
|
std::ostream& file,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
size_t srcSize,
|
size_t source_Size,
|
||||||
size_t compressedSize,
|
size_t compressed_size,
|
||||||
uint32_t crc,
|
uint32_t crc,
|
||||||
int compressionMethod,
|
int compression_method,
|
||||||
const file_time_type& modificationTime,
|
const file_time_type& last_write_time,
|
||||||
ByteBuilder& centralDir
|
ByteBuilder& central_dir
|
||||||
) {
|
) {
|
||||||
auto timestamp = to_ms_dos_timestamp(modificationTime);
|
auto timestamp = to_ms_dos_timestamp(last_write_time);
|
||||||
ByteBuilder header;
|
ByteBuilder header;
|
||||||
header.putInt32(LOCAL_FILE_SIGNATURE);
|
header.putInt32(LOCAL_FILE_SIGNATURE);
|
||||||
header.putInt16(10); // version
|
header.putInt16(10); // version
|
||||||
header.putInt16(0); // flags
|
header.putInt16(0); // flags
|
||||||
header.putInt16(compressionMethod); // compression method
|
header.putInt16(compression_method); // compression method
|
||||||
header.putInt32(timestamp); // last modification datetime
|
header.putInt32(timestamp); // last modification datetime
|
||||||
header.putInt32(crc); // crc32
|
header.putInt32(crc); // crc32
|
||||||
header.putInt32(compressedSize);
|
header.putInt32(compressed_size);
|
||||||
header.putInt32(srcSize);
|
header.putInt32(source_Size);
|
||||||
header.putInt16(name.length());
|
header.putInt16(name.length());
|
||||||
header.putInt16(0); // extra field length
|
header.putInt16(0); // extra field length
|
||||||
header.put(reinterpret_cast<const ubyte*>(name.data()), name.length());
|
header.put(reinterpret_cast<const ubyte*>(name.data()), name.length());
|
||||||
|
|
||||||
size_t localHeaderOffset = file.tellp();
|
size_t local_header_offset = file.tellp();
|
||||||
file.write(reinterpret_cast<const char*>(header.data()), header.size());
|
file.write(reinterpret_cast<const char*>(header.data()), header.size());
|
||||||
|
|
||||||
centralDir.putInt32(CENTRAL_DIR_SIGNATURE);
|
central_dir.putInt32(CENTRAL_DIR_SIGNATURE);
|
||||||
centralDir.putInt16(10); // version
|
central_dir.putInt16(10); // version
|
||||||
centralDir.putInt16(0); // version
|
central_dir.putInt16(0); // version
|
||||||
centralDir.putInt16(0); // flags
|
central_dir.putInt16(0); // flags
|
||||||
centralDir.putInt16(compressionMethod); // compression method
|
central_dir.putInt16(compression_method); // compression method
|
||||||
centralDir.putInt32(timestamp); // last modification datetime
|
central_dir.putInt32(timestamp); // last modification datetime
|
||||||
centralDir.putInt32(crc); // crc32
|
central_dir.putInt32(crc); // crc32
|
||||||
centralDir.putInt32(compressedSize);
|
central_dir.putInt32(compressed_size);
|
||||||
centralDir.putInt32(srcSize);
|
central_dir.putInt32(source_Size);
|
||||||
centralDir.putInt16(name.length());
|
central_dir.putInt16(name.length());
|
||||||
centralDir.putInt16(0); // extra field length
|
central_dir.putInt16(0); // extra field length
|
||||||
centralDir.putInt16(0); // file comment length
|
central_dir.putInt16(0); // file comment length
|
||||||
centralDir.putInt16(0); // disk number start
|
central_dir.putInt16(0); // disk number start
|
||||||
centralDir.putInt16(0); // internal attributes
|
central_dir.putInt16(0); // internal attributes
|
||||||
centralDir.putInt32(0); // external attributes
|
central_dir.putInt32(0); // external attributes
|
||||||
centralDir.putInt32(localHeaderOffset); // local header offset
|
central_dir.putInt32(local_header_offset); // local header offset
|
||||||
centralDir.put(reinterpret_cast<const ubyte*>(name.data()), name.length());
|
central_dir.put(reinterpret_cast<const ubyte*>(name.data()), name.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t write_zip(
|
static size_t write_zip(
|
||||||
const std::string& root,
|
const std::string& root,
|
||||||
const path& folder,
|
const path& folder,
|
||||||
std::ostream& file,
|
std::ostream& file,
|
||||||
ByteBuilder& centralDir
|
ByteBuilder& central_dir
|
||||||
) {
|
) {
|
||||||
size_t entries = 0;
|
size_t entries = 0;
|
||||||
ByteBuilder localHeader;
|
|
||||||
for (const auto& entry : io::directory_iterator(folder)) {
|
for (const auto& entry : io::directory_iterator(folder)) {
|
||||||
auto name = entry.pathPart().substr(root.length() + 1);
|
auto name = entry.pathPart().substr(root.length() + 1);
|
||||||
auto modificationTime = io::last_write_time(entry);
|
auto last_write_time = io::last_write_time(entry);
|
||||||
if (io::is_directory(entry)) {
|
if (io::is_directory(entry)) {
|
||||||
name = name + "/";
|
name = name + "/";
|
||||||
write_headers(
|
write_headers(
|
||||||
@ -387,35 +386,35 @@ static size_t write_zip(
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
COMPRESSION_NONE,
|
COMPRESSION_NONE,
|
||||||
modificationTime,
|
last_write_time,
|
||||||
centralDir
|
central_dir
|
||||||
);
|
);
|
||||||
entries += write_zip(root, entry, file, centralDir) + 1;
|
entries += write_zip(root, entry, file, central_dir) + 1;
|
||||||
} else {
|
} else {
|
||||||
auto uncompressed = io::read_bytes_buffer(entry);
|
auto uncompressed = io::read_bytes_buffer(entry);
|
||||||
uint32_t crc = crc32(0, uncompressed.data(), uncompressed.size());
|
uint32_t crc = crc32(0, uncompressed.data(), uncompressed.size());
|
||||||
memory_ostream memoryStream;
|
memory_ostream memory_stream;
|
||||||
{
|
{
|
||||||
deflate_ostream deflateStream(memoryStream);
|
deflate_ostream deflate_stream(memory_stream);
|
||||||
deflateStream.write(
|
deflate_stream.write(
|
||||||
reinterpret_cast<char*>(uncompressed.data()),
|
reinterpret_cast<char*>(uncompressed.data()),
|
||||||
uncompressed.size()
|
uncompressed.size()
|
||||||
);
|
);
|
||||||
deflateStream.flush();
|
deflate_stream.flush();
|
||||||
}
|
}
|
||||||
auto data = memoryStream.release();
|
auto data = memory_stream.release();
|
||||||
size_t dataSize = data.size();
|
size_t data_size = data.size();
|
||||||
write_headers(
|
write_headers(
|
||||||
file,
|
file,
|
||||||
name,
|
name,
|
||||||
uncompressed.size(),
|
uncompressed.size(),
|
||||||
dataSize,
|
data_size,
|
||||||
crc,
|
crc,
|
||||||
COMPRESSION_DEFLATE,
|
COMPRESSION_DEFLATE,
|
||||||
modificationTime,
|
last_write_time,
|
||||||
centralDir
|
central_dir
|
||||||
);
|
);
|
||||||
file.write(reinterpret_cast<const char*>(data.data()), dataSize);
|
file.write(reinterpret_cast<const char*>(data.data()), data_size);
|
||||||
entries++;
|
entries++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -423,12 +422,12 @@ static size_t write_zip(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void io::write_zip(const path& folder, const path& file) {
|
void io::write_zip(const path& folder, const path& file) {
|
||||||
ByteBuilder centralDir;
|
ByteBuilder central_dir;
|
||||||
auto out = io::write(file);
|
auto out = io::write(file);
|
||||||
size_t entries = write_zip(folder.pathPart(), folder, *out, centralDir);
|
size_t entries = write_zip(folder.pathPart(), folder, *out, central_dir);
|
||||||
|
|
||||||
size_t centralDirOffset = out->tellp();
|
size_t central_dir_offset = out->tellp();
|
||||||
out->write(reinterpret_cast<const char*>(centralDir.data()), centralDir.size());
|
out->write(reinterpret_cast<const char*>(central_dir.data()), central_dir.size());
|
||||||
|
|
||||||
ByteBuilder eocd;
|
ByteBuilder eocd;
|
||||||
eocd.putInt32(EOCD_SIGNATURE);
|
eocd.putInt32(EOCD_SIGNATURE);
|
||||||
@ -436,8 +435,8 @@ void io::write_zip(const path& folder, const path& file) {
|
|||||||
eocd.putInt16(0); // central dir disk
|
eocd.putInt16(0); // central dir disk
|
||||||
eocd.putInt16(entries); // num entries
|
eocd.putInt16(entries); // num entries
|
||||||
eocd.putInt16(entries); // total entries
|
eocd.putInt16(entries); // total entries
|
||||||
eocd.putInt32(centralDir.size()); // central dir size
|
eocd.putInt32(central_dir.size()); // central dir size
|
||||||
eocd.putInt32(centralDirOffset); // central dir offset
|
eocd.putInt32(central_dir_offset); // central dir offset
|
||||||
eocd.putInt16(0); // comment length
|
eocd.putInt16(0); // comment length
|
||||||
out->write(reinterpret_cast<const char*>(eocd.data()), eocd.size());
|
out->write(reinterpret_cast<const char*>(eocd.data()), eocd.size());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
return pptr()-pbase();
|
return pptr() - pbase();
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
int_type overflow(int_type c) override {
|
int_type overflow(int_type c) override {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user