fix external file load/save issue
This commit is contained in:
parent
2373dbee5b
commit
ac274d11ab
|
@ -185,21 +185,17 @@ namespace LibCmo::CK2 {
|
||||||
#pragma region Temp IO utilities
|
#pragma region Temp IO utilities
|
||||||
|
|
||||||
void CKContext::SetTempPath(CKSTRING u8_temp) {
|
void CKContext::SetTempPath(CKSTRING u8_temp) {
|
||||||
EncodingHelper::SetStdPathFromU8Path(this->m_TempFolder, u8_temp);
|
EncodingHelper::U8PathToStdPath(this->m_TempFolder, u8_temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* CKContext::OpenTempFile(CKSTRING u8_filename, CKSTRING u8_mode) {
|
std::string CKContext::GetTempFilePath(CKSTRING u8_filename) {
|
||||||
std::filesystem::path stdfilename;
|
std::filesystem::path stdfilename;
|
||||||
EncodingHelper::SetStdPathFromU8Path(stdfilename, u8_filename);
|
EncodingHelper::U8PathToStdPath(stdfilename, u8_filename);
|
||||||
|
|
||||||
auto realfile = this->m_TempFolder / stdfilename;
|
auto realfile = this->m_TempFolder / stdfilename;
|
||||||
return EncodingHelper::StdPathFOpen(realfile, u8_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* CKContext::OpenFile(CKSTRING u8_filename, CKSTRING u8_mode) {
|
std::string result;
|
||||||
std::filesystem::path stdfilename;
|
EncodingHelper::StdPathToU8Path(result, realfile);
|
||||||
EncodingHelper::SetStdPathFromU8Path(stdfilename, u8_filename);
|
return result;
|
||||||
return EncodingHelper::StdPathFOpen(stdfilename, u8_mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
|
@ -79,8 +79,7 @@ namespace LibCmo::CK2 {
|
||||||
// ========== Temp IO utilities ==========
|
// ========== Temp IO utilities ==========
|
||||||
|
|
||||||
void SetTempPath(CKSTRING u8_temp);
|
void SetTempPath(CKSTRING u8_temp);
|
||||||
FILE* OpenTempFile(CKSTRING u8_filename, CKSTRING u8_mode);
|
std::string GetTempFilePath(CKSTRING u8_filename);
|
||||||
FILE* OpenFile(CKSTRING u8_filename, CKSTRING u8_mode);
|
|
||||||
|
|
||||||
// ========== Print utilities ==========
|
// ========== Print utilities ==========
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace LibCmo::CK2 {
|
||||||
this->m_FileInfo.FileWriteMode = static_cast<CK_FILE_WRITEMODE>(rawHeader.FileWriteMode);
|
this->m_FileInfo.FileWriteMode = static_cast<CK_FILE_WRITEMODE>(rawHeader.FileWriteMode);
|
||||||
this->m_FileInfo.CKVersion = rawHeader.CKVersion;
|
this->m_FileInfo.CKVersion = rawHeader.CKVersion;
|
||||||
this->m_FileInfo.FileVersion = rawHeader.FileVersion;
|
this->m_FileInfo.FileVersion = rawHeader.FileVersion;
|
||||||
this->m_FileInfo.FileSize = static_cast<CKDWORD>(parser->GetSize());
|
this->m_FileInfo.FileSize = parser->GetSize();
|
||||||
this->m_FileInfo.ManagerCount = rawHeader.ManagerCount;
|
this->m_FileInfo.ManagerCount = rawHeader.ManagerCount;
|
||||||
this->m_FileInfo.ObjectCount = rawHeader.ObjectCount;
|
this->m_FileInfo.ObjectCount = rawHeader.ObjectCount;
|
||||||
this->m_FileInfo.MaxIDSaved = rawHeader.MaxIDSaved;
|
this->m_FileInfo.MaxIDSaved = rawHeader.MaxIDSaved;
|
||||||
|
@ -291,6 +291,7 @@ namespace LibCmo::CK2 {
|
||||||
// before reading, we need switch back to original parser.
|
// before reading, we need switch back to original parser.
|
||||||
// and skip data chunk size
|
// and skip data chunk size
|
||||||
parser = std::unique_ptr<CKBufferParser>(new CKBufferParser(ParserPtr->GetBase(), ParserPtr->GetSize(), false));
|
parser = std::unique_ptr<CKBufferParser>(new CKBufferParser(ParserPtr->GetBase(), ParserPtr->GetSize(), false));
|
||||||
|
parser->SetCursor(ParserPtr->GetCursor());
|
||||||
parser->MoveCursor(this->m_FileInfo.DataPackSize);
|
parser->MoveCursor(this->m_FileInfo.DataPackSize);
|
||||||
|
|
||||||
// then we can read it.
|
// then we can read it.
|
||||||
|
@ -312,10 +313,13 @@ namespace LibCmo::CK2 {
|
||||||
parser->Read(&filebodylen, sizeof(CKDWORD));
|
parser->Read(&filebodylen, sizeof(CKDWORD));
|
||||||
|
|
||||||
// read file body
|
// read file body
|
||||||
FILE* fp = m_Ctx->OpenTempFile(file.c_str(), "wb");
|
std::string tempfilename = m_Ctx->GetTempFilePath(file.c_str());
|
||||||
|
FILE* fp = EncodingHelper::U8FOpen(tempfilename.c_str(), "wb");
|
||||||
if (fp != nullptr) {
|
if (fp != nullptr) {
|
||||||
std::fwrite(parser->GetPtr(), sizeof(char), filebodylen, fp);
|
std::fwrite(parser->GetPtr(), sizeof(char), filebodylen, fp);
|
||||||
std::fclose(fp);
|
std::fclose(fp);
|
||||||
|
} else {
|
||||||
|
m_Ctx->OutputToConsoleEx("Fail to open temp file: %s", tempfilename.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// move to next
|
// move to next
|
||||||
|
|
|
@ -213,7 +213,7 @@ namespace LibCmo::CK2 {
|
||||||
EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
|
EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
|
||||||
|
|
||||||
CKDWORD comp_buf_size = 0;
|
CKDWORD comp_buf_size = 0;
|
||||||
void* comp_buffer = CKPackData(hdrparser->GetBase(), static_cast<CKDWORD>(hdrparser->GetSize()), comp_buf_size, m_Ctx->GetCompressionLevel());
|
void* comp_buffer = CKPackData(hdrparser->GetBase(), hdrparser->GetSize(), comp_buf_size, m_Ctx->GetCompressionLevel());
|
||||||
if (comp_buffer != nullptr) {
|
if (comp_buffer != nullptr) {
|
||||||
hdrparser = std::unique_ptr<CKBufferParser>(new CKBufferParser(comp_buffer, comp_buf_size, true));
|
hdrparser = std::unique_ptr<CKBufferParser>(new CKBufferParser(comp_buffer, comp_buf_size, true));
|
||||||
rawHeader.Hdr1PackSize = comp_buf_size;
|
rawHeader.Hdr1PackSize = comp_buf_size;
|
||||||
|
@ -260,7 +260,7 @@ namespace LibCmo::CK2 {
|
||||||
EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
|
EnumsHelper::Has(fileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
|
||||||
|
|
||||||
CKDWORD comp_buf_size = 0;
|
CKDWORD comp_buf_size = 0;
|
||||||
void* comp_buffer = CKPackData(datparser->GetBase(), static_cast<CKDWORD>(datparser->GetSize()), comp_buf_size, m_Ctx->GetCompressionLevel());
|
void* comp_buffer = CKPackData(datparser->GetBase(), datparser->GetSize(), comp_buf_size, m_Ctx->GetCompressionLevel());
|
||||||
if (comp_buffer != nullptr) {
|
if (comp_buffer != nullptr) {
|
||||||
datparser = std::unique_ptr<CKBufferParser>(new CKBufferParser(comp_buffer, comp_buf_size, true));
|
datparser = std::unique_ptr<CKBufferParser>(new CKBufferParser(comp_buffer, comp_buf_size, true));
|
||||||
rawHeader.DataPackSize = comp_buf_size;
|
rawHeader.DataPackSize = comp_buf_size;
|
||||||
|
@ -296,7 +296,7 @@ namespace LibCmo::CK2 {
|
||||||
|
|
||||||
// ========== Open File & Write Essential Data ==========
|
// ========== Open File & Write Essential Data ==========
|
||||||
// open file and test
|
// open file and test
|
||||||
FILE* fs = m_Ctx->OpenFile(u8_filename, "wb");
|
FILE* fs = EncodingHelper::U8FOpen(u8_filename, "wb");
|
||||||
if (fs == nullptr) return CKERROR::CKERR_CANTWRITETOFILE;
|
if (fs == nullptr) return CKERROR::CKERR_CANTWRITETOFILE;
|
||||||
// write small header + header + data
|
// write small header + header + data
|
||||||
std::fwrite(&rawHeader, sizeof(CKRawFileInfo), 1, fs);
|
std::fwrite(&rawHeader, sizeof(CKRawFileInfo), 1, fs);
|
||||||
|
@ -315,15 +315,22 @@ namespace LibCmo::CK2 {
|
||||||
std::fwrite(name_conv.data(), sizeof(char), filenamelen, fs);
|
std::fwrite(name_conv.data(), sizeof(char), filenamelen, fs);
|
||||||
|
|
||||||
// try mapping file.
|
// try mapping file.
|
||||||
std::unique_ptr<VxMath::VxMemoryMappedFile> mappedFile(new VxMath::VxMemoryMappedFile(fentry.c_str()));
|
std::string tempfilename = m_Ctx->GetTempFilePath(fentry.c_str());
|
||||||
|
std::unique_ptr<VxMath::VxMemoryMappedFile> mappedFile(new VxMath::VxMemoryMappedFile(tempfilename.c_str()));
|
||||||
// write file length
|
|
||||||
CKDWORD filebodylen = static_cast<CKDWORD>(mappedFile->IsValid() ? mappedFile->GetFileSize() : 0);
|
|
||||||
std::fwrite(&filebodylen, sizeof(CKDWORD), 1, fs);
|
|
||||||
|
|
||||||
// write file body
|
|
||||||
if (mappedFile->IsValid()) {
|
if (mappedFile->IsValid()) {
|
||||||
|
// write file length
|
||||||
|
CKDWORD filebodylen = mappedFile->GetFileSize();
|
||||||
|
std::fwrite(&filebodylen, sizeof(CKDWORD), 1, fs);
|
||||||
|
|
||||||
|
// write file body
|
||||||
std::fwrite(mappedFile->GetBase(), sizeof(char), filebodylen, fs);
|
std::fwrite(mappedFile->GetBase(), sizeof(char), filebodylen, fs);
|
||||||
|
} else {
|
||||||
|
// write zero file length
|
||||||
|
CKDWORD filebodylen = 0;
|
||||||
|
std::fwrite(&filebodylen, sizeof(CKDWORD), 1, fs);
|
||||||
|
|
||||||
|
// report error
|
||||||
|
m_Ctx->OutputToConsoleEx("Fail to open temp file: %s", tempfilename.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// release mapped file
|
// release mapped file
|
||||||
|
@ -343,7 +350,7 @@ namespace LibCmo::CK2 {
|
||||||
|
|
||||||
// try open file to check whether we can write it.
|
// try open file to check whether we can write it.
|
||||||
CKERROR err;
|
CKERROR err;
|
||||||
FILE* tryfile = m_Ctx->OpenFile(filename, "ab");
|
FILE* tryfile = EncodingHelper::U8FOpen(filename, "ab");
|
||||||
if (tryfile == nullptr) {
|
if (tryfile == nullptr) {
|
||||||
err = CKERROR::CKERR_CANTWRITETOFILE;
|
err = CKERROR::CKERR_CANTWRITETOFILE;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -178,7 +178,7 @@ namespace LibCmo::EncodingHelper {
|
||||||
return CharToChar(u8_name, native_name, CP_UTF8, *token);
|
return CharToChar(u8_name, native_name, CP_UTF8, *token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetStdPathFromU8Path(std::filesystem::path& stdpath, const char* u8_path) {
|
void U8PathToStdPath(std::filesystem::path& stdpath, const char* u8_path) {
|
||||||
std::wstring intermediary;
|
std::wstring intermediary;
|
||||||
if (CharToWchar(u8_path, intermediary, CP_UTF8)) {
|
if (CharToWchar(u8_path, intermediary, CP_UTF8)) {
|
||||||
stdpath = intermediary.c_str();
|
stdpath = intermediary.c_str();
|
||||||
|
@ -187,14 +187,24 @@ namespace LibCmo::EncodingHelper {
|
||||||
stdpath = u8_path;
|
stdpath = u8_path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StdPathToU8Path(std::string& u8path, std::filesystem::path& stdpath) {
|
||||||
|
if (!WcharToChar(stdpath.wstring(), u8path, CP_UTF8)) {
|
||||||
|
// fallback
|
||||||
|
u8path = stdpath.string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FILE* StdPathFOpen(std::filesystem::path& std_filepath, const char* u8_mode) {
|
FILE* U8FOpen(const char* u8_filepath, const char* u8_mode) {
|
||||||
std::wstring wmode;
|
std::wstring wmode, wpath;
|
||||||
if (CharToWchar(u8_mode, wmode, CP_UTF8)) {
|
bool suc = CharToWchar(u8_mode, wmode, CP_UTF8);
|
||||||
return _wfopen(std_filepath.wstring().c_str(), wmode.c_str());
|
suc = suc && CharToWchar(u8_filepath, wpath, CP_UTF8);
|
||||||
|
|
||||||
|
if (suc) {
|
||||||
|
return _wfopen(wpath.c_str(), wmode.c_str());
|
||||||
} else {
|
} else {
|
||||||
// fallback
|
// fallback
|
||||||
return std::fopen(std_filepath.string().c_str(), u8_mode);
|
return std::fopen(u8_filepath, u8_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,12 +249,16 @@ namespace LibCmo::EncodingHelper {
|
||||||
return DoIconv(token->FromUtf8, u8_name, native_name);
|
return DoIconv(token->FromUtf8, u8_name, native_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetStdPathFromU8Path(std::filesystem::path& stdpath, const char* u8_path) {
|
void U8PathToStdPath(std::filesystem::path& stdpath, const char* u8_path) {
|
||||||
stdpath = u8_path;
|
stdpath = u8_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* StdPathFOpen(std::filesystem::path& std_filepath, const char* u8_mode) {
|
void StdPathToU8Path(std::string& u8path, std::filesystem::path& stdpath) {
|
||||||
return std::fopen(u8_filepath.string().c_str(), u8_mode);
|
u8path = stdpath.string();
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* U8FOpen(const char* u8_filepath, const char* u8_mode) {
|
||||||
|
return std::fopen(u8_filepath, u8_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,9 @@ namespace LibCmo::EncodingHelper {
|
||||||
bool GetUtf8VirtoolsName(const std::string& native_name, std::string& u8_name, const ENCODING_TOKEN& token);
|
bool GetUtf8VirtoolsName(const std::string& native_name, std::string& u8_name, const ENCODING_TOKEN& token);
|
||||||
bool GetNativeVirtoolsName(const std::string& u8_name, std::string& native_name, const ENCODING_TOKEN& token);
|
bool GetNativeVirtoolsName(const std::string& u8_name, std::string& native_name, const ENCODING_TOKEN& token);
|
||||||
|
|
||||||
void SetStdPathFromU8Path(std::filesystem::path& stdpath, const char* u8_path);
|
void U8PathToStdPath(std::filesystem::path& stdpath, const char* u8_path);
|
||||||
FILE* StdPathFOpen(std::filesystem::path& std_filepath, const char* u8_mode);
|
void StdPathToU8Path(std::string& u8path, std::filesystem::path& stdpath);
|
||||||
|
FILE* U8FOpen(const char* u8_filepath, const char* u8_mode);
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace LibCmo::VxMath {
|
||||||
|
|
||||||
// save file path
|
// save file path
|
||||||
#if defined(LIBCMO_OS_WIN32)
|
#if defined(LIBCMO_OS_WIN32)
|
||||||
EncodingHelper::SetStdPathFromU8Path(m_szFilePath, u8_filepath);
|
EncodingHelper::U8PathToStdPath(m_szFilePath, u8_filepath);
|
||||||
#else
|
#else
|
||||||
this->m_szFilePath = u8_filepath;
|
this->m_szFilePath = u8_filepath;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user