add io::copy, io::copy_all & fix ZipFileDevice::list
This commit is contained in:
parent
9cc55e30e3
commit
edb581bee3
@ -60,6 +60,16 @@ ZipFileDevice::Entry ZipFileDevice::readEntry() {
|
|||||||
if (entry.diskNumberStart == 0xFF) {
|
if (entry.diskNumberStart == 0xFF) {
|
||||||
throw std::runtime_error("zip64 is not supported");
|
throw std::runtime_error("zip64 is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < entry.fileName.length(); i++) {
|
||||||
|
if (entry.fileName[i] == '\\') {
|
||||||
|
entry.fileName[i] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entry.fileName[entry.fileName.length() - 1] == '/') {
|
||||||
|
entry.isDirectory = true;
|
||||||
|
entry.fileName = entry.fileName.substr(0, entry.fileName.length() - 1);
|
||||||
|
}
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,16 +92,6 @@ void ZipFileDevice::findBlob(Entry& entry) {
|
|||||||
// Skip extra field and file comment
|
// Skip extra field and file comment
|
||||||
file->seekg(nameLength + extraFieldLength, std::ios::cur);
|
file->seekg(nameLength + extraFieldLength, std::ios::cur);
|
||||||
entry.blobOffset = file->tellg();
|
entry.blobOffset = file->tellg();
|
||||||
|
|
||||||
for (size_t i = 0; i < entry.fileName.length(); i++) {
|
|
||||||
if (entry.fileName[i] == '\\') {
|
|
||||||
entry.fileName[i] = '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (entry.fileName[entry.fileName.length() - 1] == '/') {
|
|
||||||
entry.isDirectory = true;
|
|
||||||
entry.fileName = entry.fileName.substr(0, entry.fileName.length() - 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZipFileDevice::ZipFileDevice(
|
ZipFileDevice::ZipFileDevice(
|
||||||
@ -248,9 +248,16 @@ private:
|
|||||||
std::unique_ptr<PathsGenerator> ZipFileDevice::list(std::string_view path) {
|
std::unique_ptr<PathsGenerator> ZipFileDevice::list(std::string_view path) {
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
auto folder = std::string(path) + "/";
|
auto folder = std::string(path) + "/";
|
||||||
|
size_t folderLen = folder.length();
|
||||||
for (const auto& [name, entry] : entries) {
|
for (const auto& [name, entry] : entries) {
|
||||||
if (name.find(folder) == 0) {
|
if (name.find(folder) == 0) {
|
||||||
names.push_back(name);
|
size_t pos = name.find('/', folderLen);
|
||||||
|
if (pos == std::string::npos) {
|
||||||
|
names.push_back(name.substr(folderLen, pos - folderLen));
|
||||||
|
}
|
||||||
|
if (pos == name.length() - 1) {
|
||||||
|
names.push_back(name.substr(folderLen, pos - folderLen));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::make_unique<ListPathsGenerator>(std::move(names));
|
return std::make_unique<ListPathsGenerator>(std::move(names));
|
||||||
|
|||||||
@ -252,6 +252,56 @@ uint64_t io::remove_all(const io::path& file) {
|
|||||||
return device.removeAll(file.pathPart());
|
return device.removeAll(file.pathPart());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool io::copy(const io::path& src, const io::path& dst) {
|
||||||
|
auto& srcDevice = io::require_device(src.entryPoint());
|
||||||
|
auto& dstDevice = io::require_device(dst.entryPoint());
|
||||||
|
if (!srcDevice.isfile(src.pathPart())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto input = srcDevice.read(src.pathPart());
|
||||||
|
auto output = dstDevice.write(dst.pathPart());
|
||||||
|
size_t size = srcDevice.size(src.pathPart());
|
||||||
|
std::vector<char> buffer(16'384);
|
||||||
|
while (size > 0) {
|
||||||
|
size_t read = std::min(size, buffer.size());
|
||||||
|
input->read(buffer.data(), read);
|
||||||
|
auto gcount = input->gcount();
|
||||||
|
output->write(buffer.data(), gcount);
|
||||||
|
size -= gcount;
|
||||||
|
if (input->eof()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!input->good() || !output->good()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output->good();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t io::copy_all(const io::path& src, const io::path& dst) {
|
||||||
|
auto& srcDevice = io::require_device(src.entryPoint());
|
||||||
|
auto& dstDevice = io::require_device(dst.entryPoint());
|
||||||
|
auto dstPath = dst.pathPart();
|
||||||
|
if (!dstDevice.isdir(dstPath) && !dstDevice.mkdirs(dstPath)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint64_t count = 0;
|
||||||
|
for (auto& srcSubFile : directory_iterator(src)) {
|
||||||
|
auto dstSubFile = dst / srcSubFile.name();
|
||||||
|
auto srcSubPath = srcSubFile.pathPart();
|
||||||
|
auto dstSubPath = dstSubFile.pathPart();
|
||||||
|
if (srcDevice.isdir(srcSubPath)) {
|
||||||
|
if (!dstDevice.mkdirs(dstSubPath)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
count += copy_all(srcSubFile, dstSubFile);
|
||||||
|
} else if (copy(srcSubFile, dstSubFile)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
size_t io::file_size(const io::path& file) {
|
size_t io::file_size(const io::path& file) {
|
||||||
auto& device = io::require_device(file.entryPoint());
|
auto& device = io::require_device(file.entryPoint());
|
||||||
return device.size(file.pathPart());
|
return device.size(file.pathPart());
|
||||||
|
|||||||
@ -187,6 +187,15 @@ namespace io {
|
|||||||
/// @brief Remove file or empty directory
|
/// @brief Remove file or empty directory
|
||||||
bool remove(const io::path& file);
|
bool remove(const io::path& file);
|
||||||
|
|
||||||
|
/// @brief Copy src file to dst file
|
||||||
|
/// @param src source file path
|
||||||
|
/// @param dst destination file path
|
||||||
|
/// @return true if success
|
||||||
|
bool copy(const io::path& src, const io::path& dst);
|
||||||
|
|
||||||
|
/// @brief Copy all files and directories in the folder recursively
|
||||||
|
uint64_t copy_all(const io::path& src, const io::path& dst);
|
||||||
|
|
||||||
/// @brief Remove all files and directories in the folder recursively
|
/// @brief Remove all files and directories in the folder recursively
|
||||||
uint64_t remove_all(const io::path& file);
|
uint64_t remove_all(const io::path& file);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user