mirror of
https://gitee.com/openharmony/developtools_hdc
synced 2024-11-27 09:11:24 +00:00
!1490 fix: 文件夹安装解包内存申请失败问题修复
Merge pull request !1490 from liurantao/master
This commit is contained in:
commit
cc8b7be89f
@ -20,8 +20,37 @@
|
||||
#include <iostream>
|
||||
|
||||
namespace Hdc {
|
||||
|
||||
bool Decompress::DecompressToLocal(std::string decPath)
|
||||
{
|
||||
if (!CheckPath(decPath)) {
|
||||
return false;
|
||||
}
|
||||
uint8_t buff[HEADER_LEN];
|
||||
std::ifstream inFile(tarPath);
|
||||
std::optional<Entry> entry = std::nullopt;
|
||||
while (true) {
|
||||
inFile.read(reinterpret_cast<char*>(buff), HEADER_LEN);
|
||||
auto readcnt = inFile.gcount();
|
||||
if (readcnt == 0) {
|
||||
break;
|
||||
}
|
||||
if (inFile.fail() || readcnt != HEADER_LEN) {
|
||||
WRITE_LOG(LOG_FATAL, "read file error");
|
||||
break;
|
||||
}
|
||||
entry = Entry(buff, HEADER_LEN);
|
||||
if (!entry.value().CopyPayload(decPath, inFile)) {
|
||||
entry = std::nullopt;
|
||||
break;
|
||||
}
|
||||
entry = std::nullopt;
|
||||
continue;
|
||||
}
|
||||
inFile.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Decompress::CheckPath(std::string decPath)
|
||||
{
|
||||
uv_fs_t req;
|
||||
int rc = uv_fs_lstat(nullptr, &req, tarPath.c_str(), nullptr);
|
||||
@ -50,35 +79,6 @@ bool Decompress::DecompressToLocal(std::string decPath)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
uint8_t buff[HEADER_LEN];
|
||||
std::ifstream inFile(tarPath);
|
||||
std::optional<Entry> entry = std::nullopt;
|
||||
while (1) {
|
||||
inFile.read(reinterpret_cast<char*>(buff), HEADER_LEN);
|
||||
auto readcnt = inFile.gcount();
|
||||
if (readcnt == 0) {
|
||||
break;
|
||||
}
|
||||
if (inFile.fail() || readcnt != HEADER_LEN) {
|
||||
WRITE_LOG(LOG_FATAL, "read file error");
|
||||
break;
|
||||
}
|
||||
if (!entry.has_value()) {
|
||||
entry = Entry(buff, HEADER_LEN);
|
||||
if (entry.value().IsFinish()) {
|
||||
entry.value().SaveToFile(decPath);
|
||||
entry = std::nullopt;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
entry.value().AddData(buff, HEADER_LEN);
|
||||
if (entry.value().IsFinish()) {
|
||||
entry.value().SaveToFile(decPath);
|
||||
entry = std::nullopt;
|
||||
}
|
||||
}
|
||||
inFile.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -27,6 +27,7 @@ public:
|
||||
~Decompress() {}
|
||||
|
||||
bool DecompressToLocal(std::string decPath);
|
||||
bool CheckPath(std::string decPath);
|
||||
|
||||
private:
|
||||
std::vector<Entry> entrys;
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
namespace Hdc {
|
||||
|
||||
constexpr size_t ENTRY_FILE_BUFSIZE = 4 * 1024; // 4KB
|
||||
constexpr uint64_t ENTRY_MAX_FILE_SIZE = static_cast<uint64_t>(4) * 1024 * 1024 * 1024; // 4GB
|
||||
std::optional<std::string> StripPrefix(const std::string& str, const std::string& prefix)
|
||||
{
|
||||
@ -103,35 +104,17 @@ bool Entry::UpdataName(std::string name)
|
||||
return this->header.UpdataName(name);
|
||||
}
|
||||
|
||||
bool Entry::SaveToFile(std::string prefixPath)
|
||||
bool Entry::CopyPayload(std::string prefixPath, std::ifstream &inFile)
|
||||
{
|
||||
if (!IsFinish()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (this->header.FileType()) {
|
||||
case TypeFlage::ORDINARYFILE: {
|
||||
auto saveFile = prefixPath.append(GetName());
|
||||
std::ofstream file(saveFile, std::ios::out | std::ios::binary);
|
||||
if (!file.is_open()) {
|
||||
WRITE_LOG(LOG_FATAL, "open %s fail", saveFile.c_str());
|
||||
return false;
|
||||
}
|
||||
WRITE_LOG(LOG_INFO, "saveFile %s, size %ld", saveFile.c_str(), this->data.size());
|
||||
const char *pData = reinterpret_cast<const char *>(this->data.data());
|
||||
file.write(pData, this->data.size());
|
||||
file.close();
|
||||
if (file.fail()) {
|
||||
if (!PayloadToFile(prefixPath, inFile)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TypeFlage::DIRECTORY: {
|
||||
auto dirPath = prefixPath.append(GetName());
|
||||
std::string estr;
|
||||
bool b = Base::TryCreateDirectory(dirPath, estr);
|
||||
if (!b) {
|
||||
WRITE_LOG(LOG_FATAL, "mkdir failed dirPath:%s estr:%s", dirPath.c_str(), estr.c_str());
|
||||
if (!PayloadToDir(prefixPath, inFile)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -142,6 +125,71 @@ bool Entry::SaveToFile(std::string prefixPath)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Entry::PayloadToFile(std::string prefixPath, std::ifstream &inFile)
|
||||
{
|
||||
std::string saveFile = "";
|
||||
saveFile = prefixPath + GetName();
|
||||
std::ofstream outFile(saveFile, std::ios::app | std::ios::binary);
|
||||
if (!outFile.is_open()) {
|
||||
WRITE_LOG(LOG_FATAL, "PayloadToFile open %s fail", saveFile.c_str());
|
||||
return false;
|
||||
}
|
||||
bool ret = true;
|
||||
uint8_t *buffAppend = new uint8_t[ENTRY_FILE_BUFSIZE];
|
||||
while (this->needSize >= ENTRY_FILE_BUFSIZE) {
|
||||
ret = ReadAndWriteData(inFile, outFile, buffAppend, ENTRY_FILE_BUFSIZE, ENTRY_FILE_BUFSIZE);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
this->needSize -= ENTRY_FILE_BUFSIZE;
|
||||
}
|
||||
if (ret && this->needSize > 0) {
|
||||
long int paddingSize = HEADER_LEN - (this->needSize % HEADER_LEN);
|
||||
long int lastBufSize = (paddingSize == HEADER_LEN) ? this->needSize :
|
||||
this->needSize + paddingSize;
|
||||
ret = ReadAndWriteData(inFile, outFile, buffAppend, lastBufSize, this->needSize);
|
||||
}
|
||||
delete[] buffAppend;
|
||||
buffAppend = nullptr;
|
||||
outFile.close();
|
||||
this->needSize = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Entry::ReadAndWriteData(std::ifstream &inFile, std::ofstream &outFile, uint8_t *buffAppend,
|
||||
int readSize, int writeSize)
|
||||
{
|
||||
if (buffAppend == nullptr) {
|
||||
WRITE_LOG(LOG_FATAL, "ReadAndWriteData buffAppend is null");
|
||||
return false;
|
||||
}
|
||||
inFile.read(reinterpret_cast<char*>(buffAppend), readSize);
|
||||
auto readcnt = inFile.gcount();
|
||||
if (inFile.fail() || readcnt != readSize) {
|
||||
WRITE_LOG(LOG_FATAL, "ReadAndWriteData read file error");
|
||||
return false;
|
||||
}
|
||||
outFile.write(reinterpret_cast<const char*>(buffAppend), writeSize);
|
||||
if (outFile.fail()) {
|
||||
WRITE_LOG(LOG_FATAL, "ReadAndWriteData write file error");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Entry::PayloadToDir(std::string prefixPath, std::ifstream &inFile)
|
||||
{
|
||||
std::string saveFile = "";
|
||||
auto dirPath = prefixPath.append(GetName());
|
||||
std::string estr;
|
||||
bool b = Base::TryCreateDirectory(dirPath, estr);
|
||||
if (!b) {
|
||||
WRITE_LOG(LOG_FATAL, "PayloadToDir mkdir failed dirPath:%s estr:%s", dirPath.c_str(), estr.c_str());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Entry::WriteToTar(std::ofstream &file)
|
||||
{
|
||||
switch (header.FileType()) {
|
||||
@ -149,6 +197,9 @@ bool Entry::WriteToTar(std::ofstream &file)
|
||||
char buff[HEADER_LEN] = {0};
|
||||
header.GetBytes(reinterpret_cast<uint8_t *>(buff), HEADER_LEN);
|
||||
file.write(buff, HEADER_LEN);
|
||||
if (header.Size() == 0) {
|
||||
break;
|
||||
}
|
||||
std::string name = Base::UnicodeToUtf8(GetName().c_str(), true);
|
||||
std::ifstream inFile(name, std::ios::binary);
|
||||
if (!inFile) {
|
||||
|
@ -37,12 +37,16 @@ public:
|
||||
}
|
||||
|
||||
void AddData(uint8_t *data, size_t len);
|
||||
size_t Size()
|
||||
uint64_t Size()
|
||||
{
|
||||
return header.Size();
|
||||
}
|
||||
|
||||
bool SaveToFile(std::string prefixPath);
|
||||
bool CopyPayload(std::string prefixPath, std::ifstream &inFile);
|
||||
bool PayloadToFile(std::string prefixPath, std::ifstream &inFile);
|
||||
bool PayloadToDir(std::string prefixPath, std::ifstream &inFile);
|
||||
bool ReadAndWriteData(std::ifstream &inFile, std::ofstream &outFile, uint8_t *buffAppend,
|
||||
int readSize, int writeSize);
|
||||
bool WriteToTar(std::ofstream &file);
|
||||
|
||||
std::string GetName();
|
||||
@ -50,7 +54,7 @@ public:
|
||||
|
||||
private:
|
||||
Header header;
|
||||
size_t needSize;
|
||||
uint64_t needSize;
|
||||
std::string prefix;
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
|
@ -83,15 +83,16 @@ bool Header::UpdataName(std::string fileName)
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t Header::Size()
|
||||
uint64_t Header::Size()
|
||||
{
|
||||
std::string octalStr(reinterpret_cast<char*>(this->size));
|
||||
long num = 0;
|
||||
std::string octalStr(reinterpret_cast<char*>(this->size), (HEADER_SIZE_LEN - 1));
|
||||
uint64_t num = 0;
|
||||
WRITE_LOG(LOG_DEBUG, "header size octalStr %s", octalStr.c_str());
|
||||
if (!octalStr.empty()) {
|
||||
const int octal = 8;
|
||||
num = std::stol(octalStr, nullptr, octal);
|
||||
num = stoull(octalStr, nullptr, octal);
|
||||
}
|
||||
WRITE_LOG(LOG_DEBUG, "header size num %ld", num);
|
||||
WRITE_LOG(LOG_DEBUG, "header size num %llu", num);
|
||||
return num;
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ struct Header {
|
||||
explicit Header(uint8_t data[512], int dataLen);
|
||||
std::string Name();
|
||||
bool UpdataName(std::string fileName);
|
||||
size_t Size();
|
||||
uint64_t Size();
|
||||
void UpdataSize(size_t fileLen);
|
||||
TypeFlage FileType();
|
||||
void UpdataFileType(TypeFlage fileType);
|
||||
|
Loading…
Reference in New Issue
Block a user