fully remove dassault garbage code
This commit is contained in:
parent
d32ed302d1
commit
bf7c669ce6
|
@ -3,25 +3,6 @@
|
||||||
|
|
||||||
namespace LibCmo {
|
namespace LibCmo {
|
||||||
|
|
||||||
|
|
||||||
#pragma region CKMinContext
|
|
||||||
|
|
||||||
CKMinContext::CKMinContext() {
|
|
||||||
|
|
||||||
}
|
|
||||||
CKMinContext::~CKMinContext() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CKMinContext::Printf(CKSTRING fmt, ...) {
|
|
||||||
va_list argptr;
|
|
||||||
va_start(argptr, fmt);
|
|
||||||
vfprintf(stdout, fmt, argptr);
|
|
||||||
va_end(argptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
#pragma region CKBufferParser
|
#pragma region CKBufferParser
|
||||||
|
|
||||||
CKBufferParser::CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) :
|
CKBufferParser::CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) :
|
||||||
|
@ -36,6 +17,16 @@ namespace LibCmo {
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region CKFileInfo
|
||||||
|
|
||||||
|
CKFileInfo::CKFileInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
CKFileInfo::~CKFileInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region CKFileObject
|
#pragma region CKFileObject
|
||||||
|
|
||||||
LibCmo::CKFileObject::CKFileObject() :
|
LibCmo::CKFileObject::CKFileObject() :
|
||||||
|
@ -49,6 +40,25 @@ namespace LibCmo {
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region CKFileManagerData
|
||||||
|
|
||||||
|
CKFileManagerData::CKFileManagerData() {
|
||||||
|
}
|
||||||
|
|
||||||
|
CKFileManagerData::~CKFileManagerData() {
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region CKFilePluginDependencies
|
||||||
|
|
||||||
|
CKFilePluginDependencies::CKFilePluginDependencies() {
|
||||||
|
}
|
||||||
|
|
||||||
|
CKFilePluginDependencies::~CKFilePluginDependencies() {
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region ShallowDocument
|
#pragma region ShallowDocument
|
||||||
|
|
||||||
|
@ -74,12 +84,10 @@ namespace LibCmo {
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
#pragma region CKFile Misc
|
#pragma region CKFile Misc
|
||||||
|
|
||||||
CKFile::CKFile(CKMinContext* ctx) :
|
CKFile::CKFile(CKMinContext* ctx) :
|
||||||
m_MappedFile(nullptr), m_FileName(),
|
m_FileName(), m_MinCtx(ctx) {
|
||||||
m_MinCtx(ctx) {
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +95,6 @@ namespace LibCmo {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,25 +5,10 @@
|
||||||
|
|
||||||
#include "VxMemoryMappedFile.hpp"
|
#include "VxMemoryMappedFile.hpp"
|
||||||
#include "CKStateChunk.hpp"
|
#include "CKStateChunk.hpp"
|
||||||
#include "VTObjects.hpp"
|
#include "CKMinContext.hpp"
|
||||||
|
|
||||||
namespace LibCmo {
|
namespace LibCmo {
|
||||||
|
|
||||||
class CKMinContext {
|
|
||||||
public:
|
|
||||||
CKMinContext();
|
|
||||||
CKMinContext(const CKMinContext&) = delete;
|
|
||||||
CKMinContext& operator=(const CKMinContext&) = delete;
|
|
||||||
~CKMinContext();
|
|
||||||
|
|
||||||
void Printf(CKSTRING fmt, ...);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::string NameEncoding;
|
|
||||||
std::string TempFolder;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CKBufferParser {
|
class CKBufferParser {
|
||||||
private:
|
private:
|
||||||
char* m_MemBegin;
|
char* m_MemBegin;
|
||||||
|
@ -103,16 +88,14 @@ namespace LibCmo {
|
||||||
class CKFileObject {
|
class CKFileObject {
|
||||||
public:
|
public:
|
||||||
CKFileObject();
|
CKFileObject();
|
||||||
CKFileObject(const CKFileObject&) = delete;
|
//CKFileObject(const CKFileObject&) = delete;
|
||||||
CKFileObject& operator=(const CKFileObject&) = delete;
|
//CKFileObject& operator=(const CKFileObject&) = delete;
|
||||||
~CKFileObject();
|
~CKFileObject();
|
||||||
|
|
||||||
CK_ID ObjectId;
|
CK_ID ObjectId;
|
||||||
CK_CLASSID ObjectCid;
|
CK_CLASSID ObjectCid;
|
||||||
std::string Name;
|
std::string Name;
|
||||||
CKStateChunk* Data;
|
CKStateChunk* Data;
|
||||||
CKDWORD PostPackSize;
|
|
||||||
CKDWORD PrePackSize;
|
|
||||||
CKDWORD FileIndex;
|
CKDWORD FileIndex;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -121,8 +104,8 @@ namespace LibCmo {
|
||||||
class CKFileManagerData {
|
class CKFileManagerData {
|
||||||
public:
|
public:
|
||||||
CKFileManagerData();
|
CKFileManagerData();
|
||||||
CKFileManagerData(const CKFileManagerData&) = delete;
|
//CKFileManagerData(const CKFileManagerData&) = delete;
|
||||||
CKFileManagerData& operator=(const CKFileManagerData&) = delete;
|
//CKFileManagerData& operator=(const CKFileManagerData&) = delete;
|
||||||
~CKFileManagerData();
|
~CKFileManagerData();
|
||||||
|
|
||||||
CKStateChunk* Data;
|
CKStateChunk* Data;
|
||||||
|
@ -134,8 +117,8 @@ namespace LibCmo {
|
||||||
class CKFilePluginDependencies {
|
class CKFilePluginDependencies {
|
||||||
public:
|
public:
|
||||||
CKFilePluginDependencies();
|
CKFilePluginDependencies();
|
||||||
CKFilePluginDependencies(const CKFilePluginDependencies&) = delete;
|
//CKFilePluginDependencies(const CKFilePluginDependencies&) = delete;
|
||||||
CKFilePluginDependencies& operator=(const CKFilePluginDependencies&) = delete;
|
//CKFilePluginDependencies& operator=(const CKFilePluginDependencies&) = delete;
|
||||||
~CKFilePluginDependencies();
|
~CKFilePluginDependencies();
|
||||||
|
|
||||||
CK_PLUGIN_TYPE m_PluginCategory;
|
CK_PLUGIN_TYPE m_PluginCategory;
|
||||||
|
@ -239,19 +222,13 @@ namespace LibCmo {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// reader function and variables
|
// reader function and variables
|
||||||
CKERROR PrepareLoad(CKSTRING u8_filename);
|
CKERROR ReadFileHeader(CKBufferParser* ParserPtr, CKFileData::ShallowDocument* doc);
|
||||||
CKERROR ReadFileHeader(CKBufferParser* ParserPtr);
|
CKERROR ReadFileData(CKBufferParser* ParserPtr, CKFileData::ShallowDocument* doc);
|
||||||
CKERROR ReadFileData(CKBufferParser* ParserPtr);
|
|
||||||
|
|
||||||
CKFileData::ShallowDocument* m_ShallowDoc;
|
|
||||||
CKFileData::DeepDocument* m_DeepDoc;
|
|
||||||
|
|
||||||
// writer function and varibales
|
// writer function and varibales
|
||||||
|
|
||||||
// shared function and variables
|
// shared function and variables
|
||||||
std::string m_FileName;
|
std::string m_FileName;
|
||||||
VxMemoryMappedFile* m_MappedFile;
|
|
||||||
|
|
||||||
CKMinContext* m_MinCtx;
|
CKMinContext* m_MinCtx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,47 +11,45 @@ namespace LibCmo {
|
||||||
* No need to support them.
|
* No need to support them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CKERROR CKFile::PrepareLoad(CKSTRING u8_filename) {
|
CKERROR CKFile::ShallowLoad(CKSTRING u8_filename, CKFileData::ShallowDocument** out_doc) {
|
||||||
// assign file name
|
// preset value
|
||||||
this->m_FileName = u8_filename;
|
*out_doc = nullptr;
|
||||||
// create mapped file
|
|
||||||
this->m_MappedFile = new(std::nothrow) VxMemoryMappedFile(this->m_FileName.c_str());
|
// check file and open memory
|
||||||
if (this->m_MappedFile == nullptr) {
|
if (u8_filename == nullptr) return CKERROR::CKERR_INVALIDPARAMETER;
|
||||||
|
std::unique_ptr<VxMemoryMappedFile> mappedFile(new(std::nothrow) VxMemoryMappedFile(u8_filename));
|
||||||
|
if (mappedFile == nullptr) {
|
||||||
this->m_MinCtx->Printf("Out of memory when creating Memory File.");
|
this->m_MinCtx->Printf("Out of memory when creating Memory File.");
|
||||||
return CKERROR::CKERR_OUTOFMEMORY;
|
return CKERROR::CKERR_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
if (!this->m_MappedFile->IsValid()) {
|
if (!mappedFile->IsValid()) {
|
||||||
this->m_MinCtx->Printf("Fail to create Memory File for \"%s\".", this->m_FileName.c_str());
|
this->m_MinCtx->Printf("Fail to create Memory File for \"%s\".", this->m_FileName.c_str());
|
||||||
return CKERROR::CKERR_INVALIDFILE;
|
return CKERROR::CKERR_INVALIDFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CKERROR::CKERR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
CKERROR CKFile::ShallowLoad(CKSTRING u8_filename, CKFileData::ShallowDocument** out_doc) {
|
|
||||||
// check file and open memory
|
|
||||||
if (u8_filename == nullptr) return CKERROR::CKERR_INVALIDPARAMETER;
|
|
||||||
CKERROR err = PrepareLoad(u8_filename);
|
|
||||||
if (err != CKERROR::CKERR_OK) return err;
|
|
||||||
|
|
||||||
// create document
|
// create document
|
||||||
this->m_ShallowDoc = new(std::nothrow) CKFileData::ShallowDocument();
|
std::unique_ptr<CKFileData::ShallowDocument> doc(new(std::nothrow) CKFileData::ShallowDocument());
|
||||||
if (this->m_ShallowDoc == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
|
if (doc == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
|
||||||
|
|
||||||
// create buffer and start loading
|
// create buffer and start loading
|
||||||
CKBufferParser parser(this->m_MappedFile->GetBase(), this->m_MappedFile->GetFileSize(), false);
|
std::unique_ptr<CKBufferParser> parser(new(std::nothrow) CKBufferParser(mappedFile->GetBase(), mappedFile->GetFileSize(), false));
|
||||||
err = this->ReadFileHeader(&parser);
|
CKERROR err = this->ReadFileHeader(parser.get(), doc.get());
|
||||||
if (err != CKERROR::CKERR_OK) return err;
|
if (err != CKERROR::CKERR_OK) return err;
|
||||||
err = this->ReadFileData(&parser);
|
err = this->ReadFileData(parser.get(), doc.get());
|
||||||
if (err != CKERROR::CKERR_OK) return err;
|
if (err != CKERROR::CKERR_OK) return err;
|
||||||
|
|
||||||
// free all data
|
// unbind document and assign it
|
||||||
this->ClearData();
|
*out_doc = doc.release();
|
||||||
|
// other data will be free automatically
|
||||||
return CKERROR::CKERR_OK;
|
return CKERROR::CKERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CKERROR CKFile::ReadFileHeader(CKBufferParser* ParserPtr) {
|
CKERROR CKFile::ReadFileHeader(CKBufferParser* ParserPtr, CKFileData::ShallowDocument* doc) {
|
||||||
std::unique_ptr<CKBufferParser> parser(new(std::nothrow) CKBufferParser(ParserPtr->GetBase(), ParserPtr->GetSize(), false));
|
std::unique_ptr<CKBufferParser> parser(new(std::nothrow) CKBufferParser(ParserPtr->GetBase(), ParserPtr->GetSize(), false));
|
||||||
|
if (parser == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
|
||||||
|
parser->SetCursor(ParserPtr->GetCursor());
|
||||||
|
|
||||||
|
std::string name_conv;
|
||||||
|
|
||||||
// ========== read header ==========
|
// ========== read header ==========
|
||||||
// check header size
|
// check header size
|
||||||
|
@ -73,23 +71,23 @@ namespace LibCmo {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== assign value ==========
|
// ========== assign value ==========
|
||||||
this->m_ShallowDoc->m_FileInfo.ProductVersion = rawHeader.ProductVersion;
|
doc->m_FileInfo.ProductVersion = rawHeader.ProductVersion;
|
||||||
this->m_ShallowDoc->m_FileInfo.ProductBuild = rawHeader.ProductBuild;
|
doc->m_FileInfo.ProductBuild = rawHeader.ProductBuild;
|
||||||
this->m_ShallowDoc->m_FileInfo.FileWriteMode = static_cast<CK_FILE_WRITEMODE>(rawHeader.FileWriteMode);
|
doc->m_FileInfo.FileWriteMode = static_cast<CK_FILE_WRITEMODE>(rawHeader.FileWriteMode);
|
||||||
this->m_ShallowDoc->m_FileInfo.CKVersion = rawHeader.CKVersion;
|
doc->m_FileInfo.CKVersion = rawHeader.CKVersion;
|
||||||
this->m_ShallowDoc->m_FileInfo.FileVersion = rawHeader.FileVersion;
|
doc->m_FileInfo.FileVersion = rawHeader.FileVersion;
|
||||||
this->m_ShallowDoc->m_FileInfo.FileSize = parser->GetSize();
|
doc->m_FileInfo.FileSize = parser->GetSize();
|
||||||
this->m_ShallowDoc->m_FileInfo.ManagerCount = rawHeader.ManagerCount;
|
doc->m_FileInfo.ManagerCount = rawHeader.ManagerCount;
|
||||||
this->m_ShallowDoc->m_FileInfo.ObjectCount = rawHeader.ObjectCount;
|
doc->m_FileInfo.ObjectCount = rawHeader.ObjectCount;
|
||||||
this->m_ShallowDoc->m_FileInfo.MaxIDSaved = rawHeader.MaxIDSaved;
|
doc->m_FileInfo.MaxIDSaved = rawHeader.MaxIDSaved;
|
||||||
this->m_ShallowDoc->m_FileInfo.Hdr1PackSize = rawHeader.FileVersion >= 8 ? rawHeader.Hdr1PackSize : 0u;
|
doc->m_FileInfo.Hdr1PackSize = rawHeader.FileVersion >= 8 ? rawHeader.Hdr1PackSize : 0u;
|
||||||
this->m_ShallowDoc->m_FileInfo.Hdr1UnPackSize = rawHeader.FileVersion >= 8 ? rawHeader.Hdr1UnPackSize : 0u;
|
doc->m_FileInfo.Hdr1UnPackSize = rawHeader.FileVersion >= 8 ? rawHeader.Hdr1UnPackSize : 0u;
|
||||||
this->m_ShallowDoc->m_FileInfo.DataPackSize = rawHeader.DataPackSize;
|
doc->m_FileInfo.DataPackSize = rawHeader.DataPackSize;
|
||||||
this->m_ShallowDoc->m_FileInfo.DataUnPackSize = rawHeader.DataUnPackSize;
|
doc->m_FileInfo.DataUnPackSize = rawHeader.DataUnPackSize;
|
||||||
this->m_ShallowDoc->m_FileInfo.Crc = rawHeader.Crc;
|
doc->m_FileInfo.Crc = rawHeader.Crc;
|
||||||
|
|
||||||
// ========== crc and body unpacker ==========
|
// ========== crc and body unpacker ==========
|
||||||
if (this->m_ShallowDoc->m_FileInfo.FileVersion >= 8) {
|
if (doc->m_FileInfo.FileVersion >= 8) {
|
||||||
// crc checker for file ver >= 8
|
// crc checker for file ver >= 8
|
||||||
// reset crc field of header
|
// reset crc field of header
|
||||||
rawHeader.Crc = 0u;
|
rawHeader.Crc = 0u;
|
||||||
|
@ -97,19 +95,22 @@ namespace LibCmo {
|
||||||
// compute crc
|
// compute crc
|
||||||
CKDWORD gotten_crc = CKComputeDataCRC(&rawHeader, sizeof(CKRawFileInfo), 0u);
|
CKDWORD gotten_crc = CKComputeDataCRC(&rawHeader, sizeof(CKRawFileInfo), 0u);
|
||||||
parser->SetCursor(sizeof(CKRawFileInfo));
|
parser->SetCursor(sizeof(CKRawFileInfo));
|
||||||
gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_ShallowDoc->m_FileInfo.Hdr1PackSize, gotten_crc);
|
gotten_crc = CKComputeDataCRC(parser->GetPtr(), doc->m_FileInfo.Hdr1PackSize, gotten_crc);
|
||||||
parser->MoveCursor(this->m_ShallowDoc->m_FileInfo.Hdr1PackSize);
|
parser->MoveCursor(doc->m_FileInfo.Hdr1PackSize);
|
||||||
gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_ShallowDoc->m_FileInfo.DataPackSize, gotten_crc);
|
gotten_crc = CKComputeDataCRC(parser->GetPtr(), doc->m_FileInfo.DataPackSize, gotten_crc);
|
||||||
|
|
||||||
if (gotten_crc != this->m_ShallowDoc->m_FileInfo.Crc) return CKERROR::CKERR_FILECRCERROR;
|
if (gotten_crc != doc->m_FileInfo.Crc) {
|
||||||
|
this->m_MinCtx->Printf("Virtools file CRC error.");
|
||||||
|
return CKERROR::CKERR_FILECRCERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// reset cursor
|
// reset cursor
|
||||||
parser->SetCursor(sizeof(CKRawFileInfo));
|
parser->SetCursor(sizeof(CKRawFileInfo));
|
||||||
|
|
||||||
// compare size to decide wheher use compress feature
|
// compare size to decide wheher use compress feature
|
||||||
void* decomp_buffer = CKUnPackData(this->m_ShallowDoc->m_FileInfo.Hdr1UnPackSize, parser->GetPtr(), this->m_ShallowDoc->m_FileInfo.Hdr1PackSize);
|
void* decomp_buffer = CKUnPackData(doc->m_FileInfo.Hdr1UnPackSize, parser->GetPtr(), doc->m_FileInfo.Hdr1PackSize);
|
||||||
if (decomp_buffer != nullptr) {
|
if (decomp_buffer != nullptr) {
|
||||||
parser = std::unique_ptr<CKBufferParser>(new(std::nothrow) CKBufferParser(decomp_buffer, this->m_ShallowDoc->m_FileInfo.Hdr1UnPackSize, true));
|
parser = std::unique_ptr<CKBufferParser>(new(std::nothrow) CKBufferParser(decomp_buffer, doc->m_FileInfo.Hdr1UnPackSize, true));
|
||||||
if (parser == nullptr) {
|
if (parser == nullptr) {
|
||||||
delete[] decomp_buffer;
|
delete[] decomp_buffer;
|
||||||
return CKERROR::CKERR_OUTOFMEMORY;
|
return CKERROR::CKERR_OUTOFMEMORY;
|
||||||
|
@ -119,14 +120,14 @@ namespace LibCmo {
|
||||||
|
|
||||||
// ========== object list read ==========
|
// ========== object list read ==========
|
||||||
// file ver >= 7 have this features
|
// file ver >= 7 have this features
|
||||||
if (this->m_ShallowDoc->m_FileInfo.FileVersion >= 7) {
|
{
|
||||||
// apply max id saved
|
// apply max id saved
|
||||||
this->m_ShallowDoc->m_SaveIDMax = this->m_ShallowDoc->m_FileInfo.MaxIDSaved;
|
doc->m_SaveIDMax = doc->m_FileInfo.MaxIDSaved;
|
||||||
// resize
|
// resize
|
||||||
this->m_ShallowDoc->m_FileObjects.resize(this->m_ShallowDoc->m_FileInfo.ObjectCount);
|
doc->m_FileObjects.resize(doc->m_FileInfo.ObjectCount);
|
||||||
|
|
||||||
// read data
|
// read data
|
||||||
for (auto& fileobj : this->m_ShallowDoc->m_FileObjects) {
|
for (auto& fileobj : doc->m_FileObjects) {
|
||||||
// read basic fields
|
// read basic fields
|
||||||
parser->Read(&(fileobj.ObjectId), sizeof(CK_ID));
|
parser->Read(&(fileobj.ObjectId), sizeof(CK_ID));
|
||||||
parser->Read(&(fileobj.ObjectCid), sizeof(CK_CLASSID));
|
parser->Read(&(fileobj.ObjectCid), sizeof(CK_CLASSID));
|
||||||
|
@ -135,8 +136,9 @@ namespace LibCmo {
|
||||||
CKDWORD namelen;
|
CKDWORD namelen;
|
||||||
parser->Read(&namelen, sizeof(CKDWORD));
|
parser->Read(&namelen, sizeof(CKDWORD));
|
||||||
if (namelen != 0) {
|
if (namelen != 0) {
|
||||||
fileobj.Name.resize(namelen);
|
name_conv.resize(namelen);
|
||||||
parser->Read(fileobj.Name.data(), namelen);
|
parser->Read(name_conv.data(), namelen);
|
||||||
|
m_MinCtx->GetUtf8ObjectName(name_conv, fileobj.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,14 +146,14 @@ namespace LibCmo {
|
||||||
// ========== dep list read ==========
|
// ========== dep list read ==========
|
||||||
// file ver >= 8 have this feature
|
// file ver >= 8 have this feature
|
||||||
bool noDepLost = true;
|
bool noDepLost = true;
|
||||||
if (this->m_ShallowDoc->m_FileInfo.FileVersion >= 8) {
|
if (doc->m_FileInfo.FileVersion >= 8) {
|
||||||
// get size and resize
|
// get size and resize
|
||||||
CKDWORD depSize;
|
CKDWORD depSize;
|
||||||
parser->Read(&depSize, sizeof(CKDWORD));
|
parser->Read(&depSize, sizeof(CKDWORD));
|
||||||
this->m_ShallowDoc->m_PluginDep.resize(depSize);
|
doc->m_PluginDep.resize(depSize);
|
||||||
|
|
||||||
CKDWORD guid_size;
|
CKDWORD guid_size;
|
||||||
for (auto& dep : this->m_ShallowDoc->m_PluginDep) {
|
for (auto& dep : doc->m_PluginDep) {
|
||||||
// read category
|
// read category
|
||||||
parser->Read(&(dep.m_PluginCategory), sizeof(CK_PLUGIN_TYPE));
|
parser->Read(&(dep.m_PluginCategory), sizeof(CK_PLUGIN_TYPE));
|
||||||
// get size and resize
|
// get size and resize
|
||||||
|
@ -167,7 +169,7 @@ namespace LibCmo {
|
||||||
|
|
||||||
// ========== included file list read ==========
|
// ========== included file list read ==========
|
||||||
// file ver >= 8 have this feature
|
// file ver >= 8 have this feature
|
||||||
if (this->m_ShallowDoc->m_FileInfo.FileVersion >= 8) {
|
if (doc->m_FileInfo.FileVersion >= 8) {
|
||||||
// MARK: i don't knwo what is this!
|
// MARK: i don't knwo what is this!
|
||||||
int32_t hasIncludedFile;
|
int32_t hasIncludedFile;
|
||||||
parser->Read(&hasIncludedFile, sizeof(int32_t));
|
parser->Read(&hasIncludedFile, sizeof(int32_t));
|
||||||
|
@ -176,20 +178,173 @@ namespace LibCmo {
|
||||||
// read included file size and resize
|
// read included file size and resize
|
||||||
CKDWORD includedFileCount;
|
CKDWORD includedFileCount;
|
||||||
parser->Read(&includedFileCount, sizeof(CKDWORD));
|
parser->Read(&includedFileCount, sizeof(CKDWORD));
|
||||||
this->m_ShallowDoc->m_IncludedFiles.resize(includedFileCount);
|
doc->m_IncludedFiles.resize(includedFileCount);
|
||||||
|
|
||||||
hasIncludedFile -= 4;
|
hasIncludedFile -= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// backward pos
|
// MARK: backward pos
|
||||||
parser->SetCursor(hasIncludedFile);
|
// backward with 0?
|
||||||
|
parser->MoveCursor(hasIncludedFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== sync main parser ==========
|
||||||
|
if (doc->m_FileInfo.FileVersion >= 8) {
|
||||||
|
// file ver >= 8, use header offset
|
||||||
|
// because it have compress feature
|
||||||
|
ParserPtr->SetCursor(doc->m_FileInfo.Hdr1PackSize + sizeof(CKRawFileInfo));
|
||||||
|
} else {
|
||||||
|
// otherwise, sync with current parser.
|
||||||
|
ParserPtr->SetCursor(parser->GetCursor());
|
||||||
}
|
}
|
||||||
|
|
||||||
return CKERROR::CKERR_OK;
|
return CKERROR::CKERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CKERROR CKFile::ReadFileData(CKBufferParser* ParserPtr) {
|
CKERROR CKFile::ReadFileData(CKBufferParser* ParserPtr, CKFileData::ShallowDocument* doc) {
|
||||||
return CKERROR();
|
std::unique_ptr<CKBufferParser> parser(new(std::nothrow) CKBufferParser(ParserPtr->GetBase(), ParserPtr->GetSize(), false));
|
||||||
|
if (parser == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
|
||||||
|
parser->SetCursor(ParserPtr->GetCursor());
|
||||||
|
|
||||||
|
std::string name_conv;
|
||||||
|
|
||||||
|
// ========== compress feature process ==========
|
||||||
|
if (EnumsHelper::FlagEnumHas(doc->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
|
||||||
|
EnumsHelper::FlagEnumHas(doc->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
|
||||||
|
|
||||||
|
void* decomp_buffer = CKUnPackData(doc->m_FileInfo.DataUnPackSize, parser->GetPtr(), doc->m_FileInfo.DataPackSize);
|
||||||
|
if (decomp_buffer != nullptr) {
|
||||||
|
parser = std::unique_ptr<CKBufferParser>(new(std::nothrow) CKBufferParser(decomp_buffer, doc->m_FileInfo.DataUnPackSize, true));
|
||||||
|
|
||||||
|
if (parser == nullptr) {
|
||||||
|
delete[] decomp_buffer;
|
||||||
|
return CKERROR::CKERR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== old file crc and obj list read ==========
|
||||||
|
// only file ver < 8 run this
|
||||||
|
if (doc->m_FileInfo.FileVersion < 8) {
|
||||||
|
// check crc
|
||||||
|
CKDWORD gotten_crc = CKComputeDataCRC(
|
||||||
|
parser->GetPtr(),
|
||||||
|
parser->GetSize() - parser->GetCursor(),
|
||||||
|
0u
|
||||||
|
);
|
||||||
|
if (gotten_crc != doc->m_FileInfo.Crc) {
|
||||||
|
this->m_MinCtx->Printf("Virtools file CRC error.");
|
||||||
|
return CKERROR::CKERR_FILECRCERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: why read again? especially for file ver == 7.
|
||||||
|
// get save id max
|
||||||
|
parser->Read(&doc->m_SaveIDMax, sizeof(int32_t));
|
||||||
|
// get object count and resize
|
||||||
|
parser->Read(&doc->m_FileInfo.ObjectCount, sizeof(CKDWORD));
|
||||||
|
if (doc->m_FileObjects.empty()) {
|
||||||
|
doc->m_FileObjects.resize(doc->m_FileInfo.ObjectCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== manager read ==========
|
||||||
|
// only file ver >= 6 have this
|
||||||
|
if (doc->m_FileInfo.ManagerCount != 0) {
|
||||||
|
doc->m_FileManagersData.resize(doc->m_FileInfo.ManagerCount);
|
||||||
|
CKDWORD stateChunkLen = 0u;
|
||||||
|
bool stateChkParseSuccess = false;
|
||||||
|
|
||||||
|
for (auto& mgr : doc->m_FileManagersData) {
|
||||||
|
// read guid
|
||||||
|
parser->Read(&(mgr.Manager), sizeof(CKGUID));
|
||||||
|
|
||||||
|
// read statechunk len
|
||||||
|
parser->Read(&stateChunkLen, sizeof(CKDWORD));
|
||||||
|
// check len
|
||||||
|
if (stateChunkLen == 0) {
|
||||||
|
mgr.Data = nullptr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read statechunk
|
||||||
|
mgr.Data = new(std::nothrow) CKStateChunk();
|
||||||
|
if (mgr.Data != nullptr) {
|
||||||
|
stateChkParseSuccess = mgr.Data->ConvertFromBuffer(parser->GetPtr());
|
||||||
|
if (!stateChkParseSuccess) {
|
||||||
|
delete mgr.Data;
|
||||||
|
mgr.Data = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parser->MoveCursor(stateChunkLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== object read ==========
|
||||||
|
// only works file version >= 4. < 4 section has been removed.
|
||||||
|
if (doc->m_FileInfo.ObjectCount != 0) {
|
||||||
|
// new file reader section
|
||||||
|
CKDWORD stateChunkLen = 0u;
|
||||||
|
bool stateChkParseSuccess = false;
|
||||||
|
for (auto& obj : doc->m_FileObjects) {
|
||||||
|
// get statechunk len
|
||||||
|
parser->Read(&stateChunkLen, sizeof(CKDWORD));
|
||||||
|
// check state chunk len
|
||||||
|
if (stateChunkLen == 0) {
|
||||||
|
obj.Data = nullptr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read state chunk
|
||||||
|
obj.Data = new(std::nothrow) CKStateChunk();
|
||||||
|
if (obj.Data != nullptr) {
|
||||||
|
stateChkParseSuccess = obj.Data->ConvertFromBuffer(parser->GetPtr());
|
||||||
|
if (!stateChkParseSuccess) {
|
||||||
|
delete obj.Data;
|
||||||
|
obj.Data = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parser->MoveCursor(stateChunkLen);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== included file get ==========
|
||||||
|
// before reading, we need switch back to original parser.
|
||||||
|
// and skip data chunk size
|
||||||
|
parser = std::unique_ptr<CKBufferParser>(new(std::nothrow) CKBufferParser(ParserPtr->GetBase(), ParserPtr->GetSize(), false));
|
||||||
|
parser->MoveCursor(doc->m_FileInfo.DataPackSize);
|
||||||
|
|
||||||
|
// then we can read it.
|
||||||
|
if (doc->m_IncludedFiles.size() != 0) {
|
||||||
|
for (auto& file : doc->m_IncludedFiles) {
|
||||||
|
// get file name length and resize it
|
||||||
|
CKDWORD filenamelen = 0u;
|
||||||
|
parser->Read(&filenamelen, sizeof(CKDWORD));
|
||||||
|
name_conv.resize(filenamelen);
|
||||||
|
|
||||||
|
// read filename
|
||||||
|
if (filenamelen != 0) {
|
||||||
|
parser->Read(name_conv.data(), filenamelen);
|
||||||
|
m_MinCtx->GetUtf8ObjectName(name_conv, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read file body length
|
||||||
|
CKDWORD filebodylen = 0u;
|
||||||
|
parser->Read(&filebodylen, sizeof(CKDWORD));
|
||||||
|
|
||||||
|
// read file body
|
||||||
|
FILE* fp = m_MinCtx->OpenTempFile(file.c_str(), false);
|
||||||
|
if (fp != nullptr) {
|
||||||
|
Utils::CopyStream(parser->GetPtr(), fp, filebodylen);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to next
|
||||||
|
parser->MoveCursor(filebodylen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CKERROR::CKERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//CKERROR CKFile::Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags) {
|
//CKERROR CKFile::Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags) {
|
||||||
|
|
63
LibCmo/CKMinContext.cpp
Normal file
63
LibCmo/CKMinContext.cpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#include "VTUtils.hpp"
|
||||||
|
#include "CKMinContext.hpp"
|
||||||
|
|
||||||
|
namespace LibCmo {
|
||||||
|
|
||||||
|
#if defined(LIBCMO_OS_WIN32)
|
||||||
|
static wchar_t g_UniqueFolder[] = L"LibCmo";
|
||||||
|
#else
|
||||||
|
static char g_UniqueFolder[] = "LibCmo";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
CKMinContext::CKMinContext() :
|
||||||
|
NameEncoding(), NameEncodingToken(Encoding::ENCODING_TOKEN_DEFAULT),
|
||||||
|
TempFolder()
|
||||||
|
{
|
||||||
|
// preset for temp folder
|
||||||
|
TempFolder = std::filesystem::temp_directory_path();
|
||||||
|
TempFolder /= g_UniqueFolder;
|
||||||
|
std::filesystem::create_directory(TempFolder);
|
||||||
|
}
|
||||||
|
CKMinContext::~CKMinContext() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKMinContext::Printf(CKSTRING fmt, ...) {
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr, fmt);
|
||||||
|
vfprintf(stdout, fmt, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKMinContext::GetUtf8ObjectName(std::string& native_name, std::string& u8_name) {
|
||||||
|
Encoding::GetUtf8VirtoolsName(native_name, u8_name, this->NameEncodingToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKMinContext::GetNativeObjectName(std::string& u8_name, std::string& native_name) {
|
||||||
|
Encoding::GetNativeVirtoolsName(u8_name, native_name, this->NameEncodingToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKMinContext::SetEncoding(CKSTRING encoding) {
|
||||||
|
this->NameEncoding = encoding;
|
||||||
|
this->RefetchEncodingToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKMinContext::SetTempPath(CKSTRING u8_temp) {
|
||||||
|
Encoding::SetStdPathFromU8Path(this->TempFolder, u8_temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* CKMinContext::OpenTempFile(CKSTRING u8_filename, bool is_read) {
|
||||||
|
std::filesystem::path stdfilename;
|
||||||
|
Encoding::SetStdPathFromU8Path(stdfilename, u8_filename);
|
||||||
|
|
||||||
|
auto realfile = this->TempFolder / stdfilename;
|
||||||
|
return Encoding::OpenStdPathFile(realfile, is_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKMinContext::RefetchEncodingToken(void) {
|
||||||
|
Encoding::DestroyEncodingToken(this->NameEncodingToken);
|
||||||
|
this->NameEncodingToken = Encoding::CreateEncodingToken(this->NameEncoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
41
LibCmo/CKMinContext.hpp
Normal file
41
LibCmo/CKMinContext.hpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CKDefines.hpp"
|
||||||
|
#include "CKEnums.hpp"
|
||||||
|
#include "VTEncoding.hpp"
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace LibCmo {
|
||||||
|
|
||||||
|
// forward decl to rm recursive reference
|
||||||
|
namespace ObjsImpl { class CKObject; }
|
||||||
|
|
||||||
|
class CKMinContext {
|
||||||
|
public:
|
||||||
|
CKMinContext();
|
||||||
|
CKMinContext(const CKMinContext&) = delete;
|
||||||
|
CKMinContext& operator=(const CKMinContext&) = delete;
|
||||||
|
~CKMinContext();
|
||||||
|
|
||||||
|
void Printf(CKSTRING fmt, ...);
|
||||||
|
|
||||||
|
ObjsImpl::CKObject* CreateObject(CK_ID id, CKSTRING name);
|
||||||
|
void DestroyObject(ObjsImpl::CKObject* obj);
|
||||||
|
|
||||||
|
void GetUtf8ObjectName(std::string& native_name, std::string& u8_name);
|
||||||
|
void GetNativeObjectName(std::string& u8_name, std::string& native_name);
|
||||||
|
|
||||||
|
void SetEncoding(CKSTRING encoding);
|
||||||
|
void SetTempPath(CKSTRING u8_temp);
|
||||||
|
|
||||||
|
FILE* OpenTempFile(CKSTRING u8_filename, bool is_read);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void RefetchEncodingToken(void);
|
||||||
|
|
||||||
|
std::string NameEncoding;
|
||||||
|
Encoding::ENCODING_TOKEN NameEncodingToken;
|
||||||
|
std::filesystem::path TempFolder;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -174,10 +174,12 @@
|
||||||
<ClCompile Include="CKFile.cpp" />
|
<ClCompile Include="CKFile.cpp" />
|
||||||
<ClCompile Include="CKFileWriter.cpp" />
|
<ClCompile Include="CKFileWriter.cpp" />
|
||||||
<ClCompile Include="CKGlobals.cpp" />
|
<ClCompile Include="CKGlobals.cpp" />
|
||||||
|
<ClCompile Include="CKMinContext.cpp" />
|
||||||
<ClCompile Include="ObjsImpl\CKObject.cpp" />
|
<ClCompile Include="ObjsImpl\CKObject.cpp" />
|
||||||
<ClCompile Include="VTEncoding.cpp" />
|
<ClCompile Include="VTEncoding.cpp" />
|
||||||
<ClCompile Include="CKFileReader.cpp" />
|
<ClCompile Include="CKFileReader.cpp" />
|
||||||
<ClCompile Include="CKStateChunk.cpp" />
|
<ClCompile Include="CKStateChunk.cpp" />
|
||||||
|
<ClCompile Include="VTUtils.cpp" />
|
||||||
<ClCompile Include="VxMemoryMappedFile.cpp" />
|
<ClCompile Include="VxMemoryMappedFile.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -185,6 +187,7 @@
|
||||||
<ClInclude Include="CKEnums.hpp" />
|
<ClInclude Include="CKEnums.hpp" />
|
||||||
<ClInclude Include="CKFile.hpp" />
|
<ClInclude Include="CKFile.hpp" />
|
||||||
<ClInclude Include="CKGlobals.hpp" />
|
<ClInclude Include="CKGlobals.hpp" />
|
||||||
|
<ClInclude Include="CKMinContext.hpp" />
|
||||||
<ClInclude Include="CKStateChunk.hpp" />
|
<ClInclude Include="CKStateChunk.hpp" />
|
||||||
<ClInclude Include="VTEncoding.hpp" />
|
<ClInclude Include="VTEncoding.hpp" />
|
||||||
<ClInclude Include="VTObjects.hpp" />
|
<ClInclude Include="VTObjects.hpp" />
|
||||||
|
|
|
@ -42,6 +42,12 @@
|
||||||
<ClCompile Include="CKFile.cpp">
|
<ClCompile Include="CKFile.cpp">
|
||||||
<Filter>Sources</Filter>
|
<Filter>Sources</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="CKMinContext.cpp">
|
||||||
|
<Filter>Sources</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="VTUtils.cpp">
|
||||||
|
<Filter>Sources</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="VTUtils.hpp">
|
<ClInclude Include="VTUtils.hpp">
|
||||||
|
@ -71,5 +77,8 @@
|
||||||
<ClInclude Include="VxMemoryMappedFile.hpp">
|
<ClInclude Include="VxMemoryMappedFile.hpp">
|
||||||
<Filter>Headers</Filter>
|
<Filter>Headers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="CKMinContext.hpp">
|
||||||
|
<Filter>Headers</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -60,6 +60,16 @@ namespace LibCmo {
|
||||||
return CharToWchar(src.c_str(), dest, codepage);
|
return CharToWchar(src.c_str(), dest, codepage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CharToChar(const char* src, std::string& dest, UINT src_codepage, UINT dest_codepage) {
|
||||||
|
std::wstring intermediary;
|
||||||
|
if (!CharToWchar(src, intermediary, src_codepage)) return false;
|
||||||
|
if (!WcharToChar(intermediary, dest, dest_codepage)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool CharToChar(std::string& src, std::string& dest, UINT src_codepage, UINT dest_codepage) {
|
||||||
|
return CharToChar(src.c_str(), dest, src_codepage, dest_codepage);
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
//todo: linux implementation
|
//todo: linux implementation
|
||||||
|
@ -72,35 +82,66 @@ namespace LibCmo {
|
||||||
|
|
||||||
#if defined(LIBCMO_OS_WIN32)
|
#if defined(LIBCMO_OS_WIN32)
|
||||||
|
|
||||||
void GetUtf8VirtoolsName(std::string& native_name, std::string& u8_name, const char* u8_encoding_spec) {
|
const ENCODING_TOKEN ENCODING_TOKEN_DEFAULT = nullptr;
|
||||||
// switch encoding spec
|
|
||||||
UINT codepage = CP_ACP;
|
|
||||||
if (!GetWindowsCodePage(u8_encoding_spec, &codepage)) {
|
|
||||||
u8_name = native_name.c_str();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do convert
|
ENCODING_TOKEN CreateEncodingToken(std::string& token_string) {
|
||||||
std::wstring intermediary;
|
ENCODING_TOKEN token = new(std::nothrow) UINT();
|
||||||
if (!CharToWchar(native_name, intermediary, codepage)) {
|
if (token == nullptr) return ENCODING_TOKEN_DEFAULT;
|
||||||
u8_name = native_name.c_str();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!WcharToChar(intermediary, u8_name, CP_UTF8)) {
|
|
||||||
u8_name = native_name.c_str();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
if (!GetWindowsCodePage(token_string.c_str(), token)) {
|
||||||
|
*token = CP_ACP;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
void DestroyEncodingToken(ENCODING_TOKEN token) {
|
||||||
|
if (token != ENCODING_TOKEN_DEFAULT) {
|
||||||
|
delete token;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetWcharStdin(std::string& u8_input, std::wstring& wc_input) {
|
void GetUtf8VirtoolsName(std::string& native_name, std::string& u8_name, ENCODING_TOKEN token) {
|
||||||
// just redirect to prev func
|
if (token == ENCODING_TOKEN_DEFAULT) {
|
||||||
CharToWchar(u8_input, wc_input, CP_UTF8);
|
u8_name = native_name.c_str();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert with fallback
|
||||||
|
if (!CharToChar(native_name, u8_name, *token, CP_UTF8)) {
|
||||||
|
u8_name = native_name.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetNativeVirtoolsName(std::string& u8_name, std::string& native_name, ENCODING_TOKEN token) {
|
||||||
|
if (token == ENCODING_TOKEN_DEFAULT) {
|
||||||
|
native_name = u8_name.c_str();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert with fallback
|
||||||
|
if (!CharToChar(u8_name, native_name, CP_UTF8, *token)) {
|
||||||
|
native_name = u8_name.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetStdPathFromU8Path(std::filesystem::path& stdpath, const char* u8_path) {
|
||||||
|
std::wstring intermediary;
|
||||||
|
if (CharToWchar(u8_path, intermediary, CP_UTF8)) {
|
||||||
|
stdpath = intermediary.c_str();
|
||||||
|
} else {
|
||||||
|
// fallback
|
||||||
|
stdpath = u8_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* OpenStdPathFile(std::filesystem::path& u8_filepath, bool is_read) {
|
||||||
|
return _wfopen(u8_filepath.wstring().c_str(), is_read ? L"rb" : L"wb");
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
//todo: linux implementation
|
|
||||||
|
const ENCODING_TOKEN ENCODING_TOKEN_DEFAULT = nullptr;
|
||||||
|
|
||||||
|
//todo: linux implementation
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "VTUtils.hpp"
|
#include "VTUtils.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#if defined(LIBCMO_OS_WIN32)
|
#if defined(LIBCMO_OS_WIN32)
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -25,6 +26,9 @@ namespace LibCmo {
|
||||||
bool CharToWchar(const char* src, std::wstring& dest, UINT codepage);
|
bool CharToWchar(const char* src, std::wstring& dest, UINT codepage);
|
||||||
bool CharToWchar(std::string& src, std::wstring& dest, UINT codepage);
|
bool CharToWchar(std::string& src, std::wstring& dest, UINT codepage);
|
||||||
|
|
||||||
|
bool CharToChar(const char* src, std::string& dest, UINT src_codepage, UINT dest_codepage);
|
||||||
|
bool CharToChar(std::string& src, std::string& dest, UINT src_codepage, UINT dest_codepage);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error NO IMPLEMENTATION FOR LINUX ENCODING!
|
#error NO IMPLEMENTATION FOR LINUX ENCODING!
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,9 +39,31 @@ namespace LibCmo {
|
||||||
|
|
||||||
#if defined(LIBCMO_OS_WIN32)
|
#if defined(LIBCMO_OS_WIN32)
|
||||||
|
|
||||||
void GetUtf8VirtoolsName(std::string& native_name, std::string& u8_name, const char* u8_encoding_spec);
|
/// <summary>
|
||||||
|
/// Token is the ticket for using encoding functions.
|
||||||
|
/// It should be created by "GenerateEncodingToken" and free by "DestroyEncodingToken".
|
||||||
|
/// </summary>
|
||||||
|
using ENCODING_TOKEN = UINT*;
|
||||||
|
extern const ENCODING_TOKEN ENCODING_TOKEN_DEFAULT;
|
||||||
|
|
||||||
|
ENCODING_TOKEN CreateEncodingToken(std::string& token_string);
|
||||||
|
void DestroyEncodingToken(ENCODING_TOKEN token);
|
||||||
|
|
||||||
|
void GetUtf8VirtoolsName(std::string& native_name, std::string& u8_name, ENCODING_TOKEN token);
|
||||||
|
void GetNativeVirtoolsName(std::string& u8_name, std::string& native_name, ENCODING_TOKEN token);
|
||||||
|
|
||||||
|
void SetStdPathFromU8Path(std::filesystem::path& stdpath, const char* u8_path);
|
||||||
|
FILE* OpenStdPathFile(std::filesystem::path& u8_filepath, bool is_read);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Token is the ticket for using encoding functions.
|
||||||
|
/// It should be created by "GenerateEncodingToken" and free by "DestroyEncodingToken".
|
||||||
|
/// </summary>
|
||||||
|
using ENCODING_TOKEN = char*;
|
||||||
|
extern const ENCODING_TOKEN ENCODING_TOKEN_DEFAULT;
|
||||||
|
|
||||||
#error NO IMPLEMENTATION FOR LINUX ENCODING!
|
#error NO IMPLEMENTATION FOR LINUX ENCODING!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
24
LibCmo/VTUtils.cpp
Normal file
24
LibCmo/VTUtils.cpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include "VTUtils.hpp"
|
||||||
|
|
||||||
|
namespace LibCmo {
|
||||||
|
namespace Utils {
|
||||||
|
|
||||||
|
|
||||||
|
static constexpr const size_t CHUNK_SIZE = 10240;
|
||||||
|
void CopyStream(const void* src, FILE* dest, size_t len) {
|
||||||
|
fwrite(src, sizeof(char), len, dest);
|
||||||
|
}
|
||||||
|
void CopyStream(FILE* src, void* dest, size_t len) {
|
||||||
|
size_t expected_size = 0u;
|
||||||
|
char* p = reinterpret_cast<char*>(dest);
|
||||||
|
|
||||||
|
while (len != 0) {
|
||||||
|
expected_size = len < CHUNK_SIZE ? len : CHUNK_SIZE;
|
||||||
|
fread(p, sizeof(char), expected_size, src);
|
||||||
|
p += expected_size;
|
||||||
|
len -= expected_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,10 +41,13 @@
|
||||||
#define LIBCMO_OS_WIN32
|
#define LIBCMO_OS_WIN32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
namespace LibCmo {
|
namespace LibCmo {
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
|
void CopyStream(const void* src, FILE* dest, size_t len);
|
||||||
|
void CopyStream(FILE* src, void* dest, size_t len);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace LibCmo {
|
||||||
|
|
||||||
// save file path
|
// save file path
|
||||||
#if defined(LIBCMO_OS_WIN32)
|
#if defined(LIBCMO_OS_WIN32)
|
||||||
Encoding::CharToWchar(u8_filepath, this->m_szFilePath, CP_UTF8);
|
Encoding::SetStdPathFromU8Path(m_szFilePath, u8_filepath);
|
||||||
#else
|
#else
|
||||||
this->m_szFilePath = u8_filepath;
|
this->m_szFilePath = u8_filepath;
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,7 +26,7 @@ namespace LibCmo {
|
||||||
|
|
||||||
// open file
|
// open file
|
||||||
this->m_hFile = CreateFileW(
|
this->m_hFile = CreateFileW(
|
||||||
this->m_szFilePath.c_str(),
|
this->m_szFilePath.wstring().c_str(),
|
||||||
GENERIC_READ,
|
GENERIC_READ,
|
||||||
0, // do not share
|
0, // do not share
|
||||||
NULL, // no security
|
NULL, // no security
|
||||||
|
|
|
@ -8,23 +8,25 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
namespace LibCmo {
|
namespace LibCmo {
|
||||||
|
|
||||||
class VxMemoryMappedFile {
|
class VxMemoryMappedFile {
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
#if defined(LIBCMO_OS_WIN32)
|
#if defined(LIBCMO_OS_WIN32)
|
||||||
std::wstring m_szFilePath;
|
|
||||||
HANDLE m_hFile;
|
HANDLE m_hFile;
|
||||||
DWORD m_dwFileSizeLow, m_dwFileSizeHigh;
|
DWORD m_dwFileSizeLow, m_dwFileSizeHigh;
|
||||||
HANDLE m_hFileMapping;
|
HANDLE m_hFileMapping;
|
||||||
LPVOID m_hFileMapView;
|
LPVOID m_hFileMapView;
|
||||||
#else
|
#else
|
||||||
std::string m_szFilePath;
|
|
||||||
#error NO IMPLEMENTATION FOR LINUX MMAP!
|
#error NO IMPLEMENTATION FOR LINUX MMAP!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
std::filesystem::path m_szFilePath;
|
||||||
void* m_pMemoryMappedFileBase;
|
void* m_pMemoryMappedFileBase;
|
||||||
size_t m_cbFile;
|
size_t m_cbFile;
|
||||||
bool m_bIsValid;
|
bool m_bIsValid;
|
||||||
|
|
|
@ -11,8 +11,11 @@ namespace Unvirt {
|
||||||
std::string container;
|
std::string container;
|
||||||
|
|
||||||
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKFileInfo\n")), fout);
|
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKFileInfo\n")), fout);
|
||||||
fprintf(fout, "Version (File / CK): %" PRIu32 " / 0x%08" PRIX32 "\n",
|
fprintf(fout, "Version (File / CK): %" PRIu32 " / %02" PRIX32 "/%02" PRIX32 "/%04" PRIX32 "\n",
|
||||||
fileinfo.FileVersion, fileinfo.CKVersion
|
fileinfo.FileVersion,
|
||||||
|
(fileinfo.CKVersion >> 24) & 0xFF,
|
||||||
|
(fileinfo.CKVersion >> 16) & 0xFF,
|
||||||
|
(fileinfo.CKVersion >> 0) & 0xFFFF
|
||||||
);
|
);
|
||||||
|
|
||||||
LibCmo::CKDWORD product_series[4]{
|
LibCmo::CKDWORD product_series[4]{
|
||||||
|
|
|
@ -10,11 +10,15 @@ int main(int argc, char* argv[]) {
|
||||||
Unvirt::TerminalHelper::EnsureTerminalEncoding();
|
Unvirt::TerminalHelper::EnsureTerminalEncoding();
|
||||||
|
|
||||||
LibCmo::CKMinContext vtctx;
|
LibCmo::CKMinContext vtctx;
|
||||||
|
vtctx.SetTempPath("Temp");
|
||||||
|
vtctx.SetEncoding("850");
|
||||||
|
|
||||||
LibCmo::CKFile vtfile(&vtctx);
|
LibCmo::CKFile vtfile(&vtctx);
|
||||||
LibCmo::CKFileData::ShallowDocument* doc;
|
LibCmo::CKFileData::ShallowDocument* doc;
|
||||||
LibCmo::CKERROR err = vtfile.ShallowLoad("Language.old.nmo", &doc);
|
LibCmo::CKERROR err = vtfile.ShallowLoad("combining behaviors.cmo", &doc);
|
||||||
|
|
||||||
Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo);
|
if (doc)
|
||||||
|
Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user