update shit

This commit is contained in:
2023-03-03 11:06:26 +08:00
parent 11d05615ba
commit 599456a587
18 changed files with 602 additions and 939 deletions

View File

@ -68,20 +68,12 @@ namespace LibCmo {
class CKMinContext;
class CKStateChunk;
class CKFile;
namespace CKFileData {
class ShallowDocument;
class DeepDocument;
class HybridDocument;
}
class CKFileDocument;
// useful struct define
struct CKGUID {
union {
struct {
CKDWORD d1, d2;
};
CKDWORD d[2];
};
CKDWORD d1, d2;
constexpr CKGUID(CKDWORD gd1 = 0, CKDWORD gd2 = 0) : d1(gd1), d2(gd2) {}
CKGUID(const CKGUID& rhs) : d1(rhs.d1), d2(rhs.d2) {}
CKGUID& operator=(const CKGUID& rhs) {
@ -136,12 +128,7 @@ namespace LibCmo {
class VxMemoryMappedFile;
struct VxVector {
union {
struct {
float x, y, z;
};
float v[3];
};
float x, y, z;
VxVector() : x(0.0f), y(0.0f), z(0.0f) { ; }
VxVector(float f) : x(f), y(f), z(f) { ; }
@ -150,12 +137,7 @@ namespace LibCmo {
};
struct VxQuaternion {
union {
struct {
float x, y, z, w;
};
float v[4];
};
float x, y, z, w;
VxQuaternion() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) { ; }
VxQuaternion(float X, float Y, float Z, float W) : x(X), y(Y), z(Z), w(W) { ; }

View File

@ -64,13 +64,15 @@ namespace LibCmo::CK2 {
CKFileObject::CKFileObject() :
ObjectId(0u), ObjectCid(CK_CLASSID::CKCID_OBJECT), Name(),
Data(nullptr), FileIndex(0u) {
ObjPtr(nullptr), Data(nullptr), FileIndex(0u) {
}
CKFileObject::CKFileObject(const CKFileObject& rhs) :
ObjectId(rhs.ObjectId), ObjectCid(rhs.ObjectCid), Name(rhs.Name),
Data(rhs.Data), FileIndex(rhs.FileIndex) {
ObjPtr(rhs.ObjPtr), Data(rhs.Data), FileIndex(rhs.FileIndex) {
// CKObject is managed by CKMinContext, so we just copy its pointer.
// however, we need copy CKStateChunk.
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
}
@ -83,6 +85,10 @@ namespace LibCmo::CK2 {
this->Name = rhs.Name;
this->FileIndex = rhs.FileIndex;
// CKObject is managed by CKMinContext, so we just copy its pointer.
this->ObjPtr = rhs.ObjPtr;
// however, we need copy CKStateChunk.
this->Data = rhs.Data;
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
@ -100,11 +106,11 @@ namespace LibCmo::CK2 {
#pragma region CKFileManagerData
CKFileManagerData::CKFileManagerData() :
Data(nullptr), Manager(0u, 0u) {
MgrPtr(nullptr), Data(nullptr), Manager(0u, 0u) {
}
CKFileManagerData::CKFileManagerData(const CKFileManagerData& rhs) :
Data(rhs.Data), Manager(rhs.Manager) {
MgrPtr(rhs.MgrPtr), Data(rhs.Data), Manager(rhs.Manager) {
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
@ -114,6 +120,7 @@ namespace LibCmo::CK2 {
CKFileManagerData& CKFileManagerData::operator=(const CKFileManagerData& rhs) {
this->Manager = rhs.Manager;
this->MgrPtr = rhs.MgrPtr;
this->Data = rhs.Data;
if (this->Data != nullptr) {
@ -151,34 +158,18 @@ namespace LibCmo::CK2 {
#pragma endregion
namespace CKFileData {
#pragma region ShallowDocument
ShallowDocument::ShallowDocument() {
/*this->m_IndexByClassId.resize(static_cast<size_t>(CK_CLASSID::CKCID_MAXCLASSID));*/
}
CKFileDocument::CKFileDocument() {
/*this->m_IndexByClassId.resize(static_cast<size_t>(CK_CLASSID::CKCID_MAXCLASSID));*/
}
ShallowDocument::~ShallowDocument() {
}
#pragma endregion
#pragma region DeepDocument
DeepDocument::DeepDocument() {
/*this->m_IndexByClassId.resize(static_cast<size_t>(CK_CLASSID::CKCID_MAXCLASSID));*/
}
DeepDocument::~DeepDocument() {
}
#pragma endregion
CKFileDocument::~CKFileDocument() {
}
#pragma endregion
#pragma region CKFile Misc
CKFile::CKFile(CKMinContext* ctx) :

View File

@ -88,11 +88,12 @@ namespace LibCmo::CK2 {
CKFileObject& operator=(const CKFileObject&);
~CKFileObject();
CK_ID ObjectId;
CK_CLASSID ObjectCid;
std::string Name;
CKStateChunk* Data;
CKDWORD FileIndex;
CK_ID ObjectId; // ID of the object being load/saved (as it will be/was saved in the file)
CK_CLASSID ObjectCid; // Class Identifier of the object
CKObjectImplements::CKObject* ObjPtr; // A pointer to the object itself (as CreatedObject when loading)
std::string Name; // Name of the Object
CKStateChunk* Data; // A CKStateChunk that contains object information
CKDWORD FileIndex; // Position of the object data inside uncompressed file buffer
private:
};
@ -104,6 +105,7 @@ namespace LibCmo::CK2 {
CKFileManagerData& operator=(const CKFileManagerData&);
~CKFileManagerData();
CKManagerImplements::CKBaseManager* MgrPtr;
CKStateChunk* Data;
CKGUID Manager;
private:
@ -123,56 +125,22 @@ namespace LibCmo::CK2 {
};
namespace CKFileData {
class ShallowDocument {
public:
ShallowDocument();
ShallowDocument(const ShallowDocument&) = delete;
ShallowDocument& operator=(const ShallowDocument&) = delete;
~ShallowDocument();
class CKFileDocument {
public:
CKFileDocument();
~CKFileDocument();
int32_t m_SaveIDMax;
CKFileInfo m_FileInfo;
int32_t m_SaveIDMax;
CKFileInfo m_FileInfo;
XArray<CKFileObject> m_FileObjects;
XArray<CKFileManagerData> m_FileManagersData;
XClassArray<CKFilePluginDependencies> m_PluginDep;
/*XClassArray<XIntArray> m_IndexByClassId;*/
XClassArray<XString> m_IncludedFiles;
XArray<CKFileObject> m_FileObjects;
XArray<CKFileManagerData> m_FileManagersData;
XClassArray<CKFilePluginDependencies> m_PluginDep;
/*XClassArray<XIntArray> m_IndexByClassId;*/
XClassArray<XString> m_IncludedFiles;
private:
private:
};
class DeepDocument {
public:
DeepDocument();
DeepDocument(const DeepDocument&) = delete;
DeepDocument& operator=(const DeepDocument&) = delete;
~DeepDocument();
int32_t m_SaveIDMax;
CKFileInfo m_FileInfo;
XArray<CKObjectImplements::CKObject*> m_Objects;
/*XClassArray<XIntArray> m_IndexByClassId;*/
XClassArray<XString> m_IncludedFiles;
private:
};
class HybridDocument {
public:
HybridDocument();
HybridDocument(const HybridDocument&) = delete;
HybridDocument& operator=(const HybridDocument&) = delete;
~HybridDocument();
private:
};
}
};
class CKFile {
public:
@ -183,16 +151,10 @@ namespace LibCmo::CK2 {
void ClearData(void);
CKERROR ShallowLoad(CKSTRING u8_filename, CKFileData::ShallowDocument** out_doc);
CKERROR DeepLoad(CKSTRING u8_filename, CKFileData::DeepDocument** out_doc);
CKERROR ShallowLoad(CKSTRING u8_filename, CKFileDocument** out_doc);
CKERROR DeepLoad(CKSTRING u8_filename, CKFileDocument** out_doc);
CKERROR ShallowSave(CKSTRING u8_filename, CKFileData::ShallowDocument* in_doc);
CKERROR DeepSave(CKSTRING u8_filename, CKFileData::DeepDocument* out_doc);
CKERROR HybridSave(CKSTRING u8_filename, CKFileData::HybridDocument* out_doc);
CKERROR DestroyDocument(CKFileData::ShallowDocument* in_doc);
CKERROR DestroyDocument(CKFileData::DeepDocument* in_doc);
CKERROR DestroyDocument(CKFileData::HybridDocument* in_doc);
CKERROR Save(CKSTRING u8_filename, CKFileDocument* in_doc);
//CKERROR Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags);
//CKERROR OpenFile(CKSTRING u8_filename, CK_LOAD_FLAGS flags);
@ -218,8 +180,8 @@ namespace LibCmo::CK2 {
private:
// reader function and variables
CKERROR ReadFileHeader(CKBufferParser* ParserPtr, CKFileData::ShallowDocument* doc);
CKERROR ReadFileData(CKBufferParser* ParserPtr, CKFileData::ShallowDocument* doc);
CKERROR ReadFileHeader(CKBufferParser* ParserPtr, CKFileDocument* doc);
CKERROR ReadFileData(CKBufferParser* ParserPtr, CKFileDocument* doc);
// writer function and varibales

View File

@ -15,7 +15,7 @@ namespace LibCmo::CK2 {
* No need to support them.
*/
CKERROR CKFile::ShallowLoad(CKSTRING u8_filename, CKFileData::ShallowDocument** out_doc) {
CKERROR CKFile::ShallowLoad(CKSTRING u8_filename, CKFileDocument** out_doc) {
// preset value
*out_doc = nullptr;
@ -32,7 +32,7 @@ namespace LibCmo::CK2 {
}
// create document
std::unique_ptr<CKFileData::ShallowDocument> doc(new(std::nothrow) CKFileData::ShallowDocument());
std::unique_ptr<CKFileDocument> doc(new(std::nothrow) CKFileDocument());
if (doc == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
// create buffer and start loading
@ -48,7 +48,7 @@ namespace LibCmo::CK2 {
return CKERROR::CKERR_OK;
}
CKERROR CKFile::ReadFileHeader(CKBufferParser* ParserPtr, CKFileData::ShallowDocument* doc) {
CKERROR CKFile::ReadFileHeader(CKBufferParser* ParserPtr, CKFileDocument* doc) {
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());
@ -149,7 +149,6 @@ namespace LibCmo::CK2 {
// ========== dep list read ==========
// file ver >= 8 have this feature
bool noDepLost = true;
if (doc->m_FileInfo.FileVersion >= 8) {
// get size and resize
CKDWORD depSize;
@ -205,7 +204,7 @@ namespace LibCmo::CK2 {
return CKERROR::CKERR_OK;
}
CKERROR CKFile::ReadFileData(CKBufferParser* ParserPtr, CKFileData::ShallowDocument* doc) {
CKERROR CKFile::ReadFileData(CKBufferParser* ParserPtr, CKFileDocument* doc) {
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());
@ -351,32 +350,27 @@ namespace LibCmo::CK2 {
return CKERROR::CKERR_OK;
}
CKERROR CKFile::DeepLoad(CKSTRING u8_filename, CKFileData::DeepDocument** out_doc) {
CKERROR CKFile::DeepLoad(CKSTRING u8_filename, CKFileDocument** out_doc) {
// ========== prepare work ==========
// preset value
*out_doc = nullptr;
CKERROR err = CKERROR::CKERR_OK;
// get shallow document first
CKFileData::ShallowDocument* rawShallowDoc = nullptr;
CKERROR err = this->ShallowLoad(u8_filename, &rawShallowDoc);
CKFileDocument* rawShallowDoc = nullptr;
err = this->ShallowLoad(u8_filename, &rawShallowDoc);
if (rawShallowDoc == nullptr) return err;
std::unique_ptr<CKFileData::ShallowDocument> shallowDoc(rawShallowDoc);
// use unique ptr wrap it as a deep doc
std::unique_ptr<CKFileDocument> deepDoc(rawShallowDoc);
if (err != CKERROR::CKERR_OK) return err;
// create deep document
std::unique_ptr<CKFileData::DeepDocument> deepDoc(new(std::nothrow) CKFileData::DeepDocument());
if (deepDoc == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
// ========== create object first ==========
size_t index = 0u;
std::vector<CKObjectImplements::CKObject*> createdObjs(shallowDoc->m_FileObjects.size(), nullptr);
for (index = 0u; index < shallowDoc->m_FileObjects.size(); ++index) {
for (auto& obj : deepDoc->m_FileObjects) {
// todo: skip CK_LEVEL
// todo: resolve references
const auto& obj = shallowDoc->m_FileObjects[index];
if (obj.Data == nullptr) continue;
createdObjs[index] = m_MinCtx->CreateCKObject(obj.ObjectId, obj.ObjectCid, obj.Name.c_str());
obj.ObjPtr = m_MinCtx->CreateCKObject(obj.ObjectId, obj.ObjectCid, obj.Name.c_str());
}
// ========== CKStateChunk remap ==========
@ -387,523 +381,29 @@ namespace LibCmo::CK2 {
// todo...
// ========== analyze objects CKStateChunk ==========
for (index = 0u; index < shallowDoc->m_FileObjects.size(); ++index) {
const auto& obj = shallowDoc->m_FileObjects[index];
if (obj.Data == nullptr || createdObjs[index] == nullptr) continue;
for (auto& obj : deepDoc->m_FileObjects) {
if (obj.Data == nullptr || obj.ObjPtr == nullptr) continue;
// todo: special treat for CK_LEVEL
// try parsing data
obj.Data->StartRead();
CKERROR err = createdObjs[index]->Load(obj.Data, shallowDoc.get());
err = obj.ObjPtr->Load(obj.Data, deepDoc.get());
obj.Data->StopRead();
if (err != CKERROR::CKERR_OK) {
delete (createdObjs[index]);
createdObjs[index] = nullptr;
// if failed, delete it
m_MinCtx->DestroyCKObject(obj.ObjectId);
obj.ObjPtr = nullptr;
} else {
// add into result
deepDoc->m_Objects.push_back(createdObjs[index]);
// if success, clear CKStateChunk*
delete obj.Data;
obj.Data = nullptr;
}
}
// ========== finalize work ==========
// copy misc structure
deepDoc->m_IncludedFiles = shallowDoc->m_IncludedFiles;
deepDoc->m_SaveIDMax = shallowDoc->m_SaveIDMax;
deepDoc->m_FileInfo = shallowDoc->m_FileInfo;
// detach and return
*out_doc = deepDoc.release();
return CKERROR::CKERR_OK;
}
//CKERROR CKFile::Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags) {
// CKERROR result = this->OpenFile(u8_filename, flags);
// if (result == CKERROR::CKERR_OK || result == CKERROR::CKERR_PLUGINSMISSING) {
// result = this->LoadFileData();
// }
// return result;
//}
//CKERROR CKFile::OpenFile(CKSTRING u8_filename, CK_LOAD_FLAGS flags) {
// this->ClearData();
// if (u8_filename == nullptr) return CKERROR::CKERR_INVALIDPARAMETER;
// this->m_FileName = u8_filename;
// this->m_MappedFile = new(std::nothrow) VxMemoryMappedFile(this->m_FileName.c_str());
// if (this->m_MappedFile == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
// if (!this->m_MappedFile->IsValid()) return CKERROR::CKERR_INVALIDFILE;
// // MARK: CKContext::SetLastCmoLoaded
// return this->OpenMemory(this->m_MappedFile->GetBase(), this->m_MappedFile->GetFileSize(), flags);
//}
//CKERROR CKFile::OpenMemory(void* MemoryBuffer, size_t BufferSize, CK_LOAD_FLAGS Flags) {
// if (MemoryBuffer == nullptr) return CKERROR::CKERR_INVALIDPARAMETER;
// // compare magic words
// if (BufferSize < 0x20 || memcmp(MemoryBuffer, "Nemo", 4u)) return CKERROR::CKERR_INVALIDFILE;
// this->m_Parser = new(std::nothrow) CKBufferParser(MemoryBuffer, BufferSize, false);
// if (this->m_Parser == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
// // MARK: eliminate check of m_Parser->m_ReaderBegin
// // MARK: dword_2405F6C0 = 0;
// this->m_Flags = Flags;
// this->m_IndexByClassId.resize(static_cast<size_t>(CK_CLASSID::CKCID_MAXCLASSID));
// return this->ReadFileHeaders(&(this->m_Parser));
//}
//CKERROR CKFile::ReadFileHeaders(CKBufferParser** ParserPtr) {
// CKBufferParser* parser = *ParserPtr;
// this->m_IncludedFiles.clear();
// // ========== read header1 ==========
// CKDWORD fhdr1[8];
// CKDWORD fhdr2[8];
// if (parser->GetSize() < sizeof(fhdr1)) return CKERROR::CKERR_INVALIDFILE;
// parser->Read(fhdr1, sizeof(fhdr1));
// if (fhdr1[5]) { // it seems that there is a ZERO checker?
// memset(fhdr1, 0, sizeof(fhdr1));
// }
// // check outdated
// if (fhdr1[4] > 9) return CKERROR::CKERR_OBSOLETEVIRTOOLS;
// // ========== read header2 ==========
// // file ver < 5 do not have second header
// if (fhdr1[4] < 5) {
// memset(fhdr2, 0, sizeof(fhdr2));
// } else {
// if (parser->GetSize() < sizeof(fhdr1) + sizeof(fhdr2)) return CKERROR::CKERR_INVALIDFILE;
// parser->Read(fhdr2, sizeof(fhdr2));
// }
// // forcely reset too big product ver
// if (fhdr2[5] >= 12) {
// fhdr2[5] = 0;
// fhdr2[6] = 0x1010000;
// }
// // ========== assign value ==========
// this->m_FileInfo.ProductVersion = fhdr2[5];
// this->m_FileInfo.ProductBuild = fhdr2[6];
// this->m_FileInfo.FileWriteMode = static_cast<CK_FILE_WRITEMODE>(fhdr1[6]);
// this->m_FileInfo.CKVersion = fhdr1[3];
// this->m_FileInfo.FileVersion = fhdr1[4];
// this->m_FileInfo.FileSize = parser->GetSize();
// this->m_FileInfo.ManagerCount = fhdr2[2];
// this->m_FileInfo.ObjectCount = fhdr2[3];
// this->m_FileInfo.MaxIDSaved = fhdr2[4];
// this->m_FileInfo.Hdr1PackSize = fhdr1[7];
// this->m_FileInfo.Hdr1UnPackSize = fhdr2[7];
// this->m_FileInfo.DataPackSize = fhdr2[0];
// this->m_FileInfo.DataUnPackSize = fhdr2[1];
// this->m_FileInfo.Crc = fhdr1[2];
// // ========== crc and body unpacker ==========
// if (this->m_FileInfo.FileVersion >= 8) {
// // crc checker for file ver >= 8
// // reset crc field of header
// fhdr1[2] = 0;
// // compute crc
// CKDWORD gotten_crc = CKComputeDataCRC(&fhdr1, sizeof(fhdr1), 0u);
// parser->SetCursor(sizeof(fhdr1));
// gotten_crc = CKComputeDataCRC(parser->GetPtr(), sizeof(fhdr2), gotten_crc);
// parser->MoveCursor(sizeof(fhdr2));
// gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.Hdr1PackSize, gotten_crc);
// parser->MoveCursor(this->m_FileInfo.Hdr1PackSize);
// gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.DataPackSize, gotten_crc);
// parser->SetCursor(sizeof(fhdr1) + sizeof(fhdr2));
// if (gotten_crc != this->m_FileInfo.Crc) return CKERROR::CKERR_FILECRCERROR;
// // compare size to decide wheher use compress feature
// void* decomp_buffer = CKUnPackData(this->m_FileInfo.Hdr1UnPackSize, parser->GetPtr(), this->m_FileInfo.Hdr1PackSize);
// if (decomp_buffer != nullptr) {
// parser = new(std::nothrow) CKBufferParser(decomp_buffer, this->m_FileInfo.Hdr1UnPackSize, true);
// if (parser == nullptr) {
// delete[] decomp_buffer;
// return CKERROR::CKERR_OUTOFMEMORY;
// }
// }
// }
// // ========== object list read ==========
// // file ver >= 7 have this features
// if (this->m_FileInfo.FileVersion >= 7) {
// // apply max id saved
// this->m_SaveIDMax = this->m_FileInfo.MaxIDSaved;
// // resize
// this->m_FileObject.resize(this->m_FileInfo.ObjectCount);
// // read data
// for (auto& fileobj : this->m_FileObject) {
// // setup useless fields
// fileobj.ObjPtr = nullptr;
// fileobj.Data = nullptr;
// // read basic fields
// parser->Read(&(fileobj.Object), sizeof(CK_ID));
// parser->Read(&(fileobj.ObjectCid), sizeof(CK_CLASSID));
// parser->Read(&(fileobj.FileIndex), sizeof(CKDWORD));
// CKDWORD namelen;
// parser->Read(&namelen, sizeof(CKDWORD));
// if (namelen != 0) {
// fileobj.Name.resize(namelen);
// parser->Read(fileobj.Name.data(), namelen);
// }
// }
// }
// // ========== dep list read ==========
// // file ver >= 8 have this feature
// bool noDepLost = true;
// if (this->m_FileInfo.FileVersion >= 8) {
// // get size and resize
// CKDWORD depSize;
// parser->Read(&depSize, sizeof(CKDWORD));
// this->m_PluginDep.resize(depSize);
// CKDWORD guid_size;
// for (auto& dep : this->m_PluginDep) {
// // read category
// parser->Read(&(dep.m_PluginCategory), sizeof(CK_PLUGIN_TYPE));
// // get size and resize
// parser->Read(&guid_size, sizeof(CKDWORD));
// dep.m_Guids.resize(guid_size);
// dep.ValidGuids.resize(guid_size);
// // read data
// if (guid_size != 0) {
// parser->Read(dep.m_Guids.data(), sizeof(CKGUID) * guid_size);
// }
// // extra load flag
// if (EnumHelper::FlagEnumHas(this->m_Flags, CK_LOAD_FLAGS::CK_LOAD_CHECKDEPENDENCIES)) {
// for (size_t i = 0u; i < dep.m_Guids.size(); ++i) {
// // MARK: CKPluginManager::FindComponent
// bool plgEntryIsNull = true;
// if (plgEntryIsNull) {
// noDepLost = false;
// dep.ValidGuids[i] = false;
// } else {
// dep.ValidGuids[i] = true;
// }
// }
// }
// }
// }
// // ========== included file list read ==========
// // file ver >= 8 have this feature
// if (this->m_FileInfo.FileVersion >= 8) {
// // MARK: i don't knwo what is this!
// int32_t hasIncludedFile;
// parser->Read(&hasIncludedFile, sizeof(int32_t));
// if (hasIncludedFile > 0) {
// // read included file size and resize
// CKDWORD includedFileCount;
// parser->Read(&includedFileCount, sizeof(CKDWORD));
// this->m_IncludedFiles.resize(includedFileCount);
// hasIncludedFile -= 4;
// }
// // backward pos
// parser->SetCursor(hasIncludedFile);
// }
// // ========== read data ==========
// // restore old parser if needed
// if (parser != *ParserPtr) {
// delete parser;
// parser = *ParserPtr;
// parser->MoveCursor(this->m_FileInfo.Hdr1PackSize);
// }
// // MARK: dword_2405F6BC, dword_2405F6B8 set
// if (!(EnumHelper::FlagEnumHas(this->m_Flags, CK_LOAD_FLAGS::CK_LOAD_CHECKDEPENDENCIES) &&
// this->m_FileInfo.FileVersion < 8)) {
// // we have read all header. return result
// return noDepLost ? CKERROR::CKERR_OK : CKERROR::CKERR_PLUGINSMISSING;
// } // however, if we need check dep, and, we have not read dep list. continue read them.
// return CKERROR::CKERR_OK;
//}
//CKERROR CKFile::ReadFileData(CKBufferParser** ParserPtr) {
// CKBufferParser* parser = *ParserPtr;
// CKBufferParser* parserSrc = *ParserPtr;
// // ========== compress feature process ==========
// if (EnumHelper::FlagEnumHas(this->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
// EnumHelper::FlagEnumHas(this->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
// void* decomp_buffer = CKUnPackData(this->m_FileInfo.DataUnPackSize, parser->GetPtr(), this->m_FileInfo.DataPackSize);
// parser->MoveCursor(this->m_FileInfo.DataPackSize);
// if (decomp_buffer != nullptr) {
// parser = new(std::nothrow) CKBufferParser(decomp_buffer, this->m_FileInfo.DataUnPackSize, true);
// if (parser == nullptr) {
// delete[] decomp_buffer;
// return CKERROR::CKERR_OUTOFMEMORY;
// }
// // sync to args
// *ParserPtr = parser;
// }
// }
// // ========== old file crc and obj list read ==========
// // only file ver < 8 run this
// if (this->m_FileInfo.FileVersion < 8) {
// // very very old flag
// if (this->m_FileInfo.FileVersion < 2) {
// ;
// // MARK: dword_2405F6C0 setter
// }
// // check crc
// CKDWORD gotten_crc = CKComputeDataCRC(
// parser->GetPtr(),
// parser->GetSize() - parser->GetCursor(),
// 0u
// );
// if (gotten_crc != this->m_FileInfo.Crc) {
// // MARK: report crc error
// return CKERROR::CKERR_FILECRCERROR;
// }
// // get save id max
// parser->Read(&this->m_SaveIDMax, sizeof(int32_t));
// // get object count and resize
// parser->Read(&this->m_FileInfo.ObjectCount, sizeof(CKDWORD));
// if (this->m_FileObject.empty()) {
// this->m_FileObject.resize(this->m_FileInfo.ObjectCount);
// // MARK: ZeroMemory removed. i think it is not necessary.
// }
// }
// // ========== manager read ==========
// // only file ver >= 6 have this
// if (this->m_FileInfo.FileVersion >= 6 && this->m_FileInfo.ManagerCount != 0) {
// this->m_ManagersData.resize(this->m_FileInfo.ManagerCount);
// CKDWORD stateChunkLen = 0u;
// bool stateChkParseSuccess = false;
// for (auto& mgr : this->m_ManagersData) {
// // 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 ==========
// if (this->m_FileInfo.ObjectCount != 0) {
// if (this->m_FileInfo.FileVersion >= 4) {
// // new file reader section
// CKDWORD stateChunkLen = 0u;
// bool stateChkParseSuccess = false;
// for (auto& obj : this->m_FileObject) {
// if (this->m_FileInfo.FileVersion < 7) {
// // it seems that file ver < 7, ck id was stored first.
// parser->Read(&(obj.Object), sizeof(CK_ID));
// }
// // get statechunk len
// parser->Read(&stateChunkLen, sizeof(CKDWORD));
// // if only load behavior and current loaded obj is not behavior, give up.
// // >= 7 is corresponding with obj header version requirement
// // so don't worry about this
// if (EnumHelper::FlagEnumHas(this->m_Flags, CK_LOAD_FLAGS::CK_LOAD_ONLYBEHAVIORS) &&
// this->m_FileInfo.FileVersion >= 7 &&
// obj.ObjectCid != CK_CLASSID::CKCID_BEHAVIOR) {
// // move cursor for next one.
// parser->MoveCursor(stateChunkLen);
// continue;
// }
// // 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;
// } else {
// // get data size and fill some fields
// obj.PostPackSize = obj.Data->GetDataSize();
// obj.PrePackSize = obj.PostPackSize;
// }
// }
// parser->MoveCursor(stateChunkLen);
// }
// } else {
// // old file read section
// for (auto& obj : this->m_FileObject) {
// // read CK_ID
// parser->Read(&(obj.Object), sizeof(CK_ID));
// // get data len
// CKDWORD dataLen = 0u;
// parser->Read(&dataLen, sizeof(CKDWORD));
// // check state chunk len
// if (dataLen == 0) {
// obj.Data = nullptr;
// continue;
// }
// // MARK: set dword_2405F6C0
//
// // read class id
// CK_CLASSID clsid = CK_CLASSID::CKCID_OBJECT;
// parser->Read(&clsid, sizeof(CK_CLASSID));
// if (static_cast<uint32_t>(clsid) == UINT32_C(0)) {
// // invalid cid;
// return CKERROR::CKERR_INVALIDFILE;
// }
// // read save flags
// parser->Read(&obj.SaveFlags, sizeof(CK_FILE_WRITEMODE));
// // read statechunk len
// CKDWORD oldBufLen = 0u;
// parser->Read(&oldBufLen, sizeof(CKDWORD));
// // setup state chunk and order parse it
// obj.Data = new(std::nothrow) CKStateChunk(clsid);
// if (obj.Data != nullptr) {
// if (!obj.Data->ConvertFromOldBuffer(parser->GetPtr(), oldBufLen, dataLen, obj.SaveFlags)) {
// delete obj.Data;
// obj.Data = nullptr;
// }
// }
// // move to next
// parser->MoveCursor(oldBufLen);
// }
// // MARK: remove a weird assign: parserSrc = v46; it seems useless.
// }
// }
// // ========== object name get ==========
// // only file ver < 7 need get it from statechunk
// if (this->m_FileInfo.FileVersion < 7) {
// for (auto& obj : this->m_FileObject) {
// if (obj.Data != nullptr) {
// // TODO: CK_STATESAVE_NAME
// if (obj.Data->SeekIdentifier(1u)) {
// obj.Data->ReadString(obj.Name);
// }
// }
// }
// }
// // ========== included file get ==========
// // WARN: we use "parserSrc" to read, not "parser"!!!
// for (size_t i = 0; i < this->m_IncludedFiles.size(); ++i) {
// // get file name length and resize it
// CKDWORD filenamelen = 0u;
// parserSrc->Read(&filenamelen, sizeof(CKDWORD));
// std::string filename;
// filename.resize(filenamelen);
// // read filename
// if (filenamelen != 0) {
// parserSrc->Read(filename.data(), filenamelen);
// }
// // todo: construct temp folder path
// // and regulate file name
// // read file body length
// CKDWORD filebodylen = 0u;
// parserSrc->Read(&filebodylen, sizeof(CKDWORD));
// // todo: read file body
// parserSrc->MoveCursor(filebodylen);
// }
// // ========== free parser ==========
// if (parserSrc != parser && parserSrc != nullptr) {
// // WARN: we should free parserSrc! not free parser
// // because "parser" has synced with ParserPtr and will be freed from outside.
// delete parserSrc;
// }
// return CKERROR::CKERR_OK;
//}
//CKERROR CKFile::LoadFileData(void/*CKObjectArray list*/) {
// if (!this->m_Parser && !this->m_ReadFileDataDone) {
// return CKERROR::CKERR_INVALIDFILE;
// }
// // MARK: sub_240372EA, ctx + 193 = 1
// // if file data has not been read. read it
// CKERROR err = CKERROR::CKERR_OK;
// CKBufferParser** ParserPtr = &this->m_Parser;
// if (!this->m_ReadFileDataDone) {
// err = this->ReadFileData(ParserPtr);
// }
// // MARK: i assume FinishLoading do not calling mapped file anymore
// // free file data
// if (*ParserPtr != nullptr) {
// delete *ParserPtr;
// *ParserPtr = nullptr;
// }
// if (this->m_MappedFile != nullptr) {
// delete this->m_MappedFile;
// this->m_MappedFile = nullptr;
// }
// // if no error, do finish loading
// if (err == CKERROR::CKERR_OK) {
// this->FinishLoading(this->m_Flags);
// // MARK: dword_2405F6C0 old vt ver output
// }
// // MARK: CKContext::SetAutomaticLoadMode
// // MARK:CKContext::SetUserLoadCallback
// // MARK: sub_24037360
// // MARK: ctx + 193 = 0
// return err;
//}
//CKERROR CKFile::FinishLoading(/*CKObjectArray list, */CK_LOAD_FLAGS flags) {
// return CKERROR::CKERR_OK;
//}
}

View File

@ -9,10 +9,10 @@ namespace LibCmo::CK2::CKManagerImplements {
}
CKERROR CKBaseManager::LoadData(CKStateChunk* statechunk, CKFileData::ShallowDocument* doc) {
CKERROR CKBaseManager::LoadData(CKStateChunk* statechunk, CKFileDocument* doc) {
return CKERROR::CKERR_OK;
}
CKStateChunk* CKBaseManager::SaveData(CKFileData::ShallowDocument* doc) {
CKStateChunk* CKBaseManager::SaveData(CKFileDocument* doc) {
return nullptr;
}

View File

@ -12,8 +12,8 @@ namespace LibCmo::CK2::CKManagerImplements {
CKBaseManager& operator=(const CKBaseManager&) = delete;
virtual ~CKBaseManager();
virtual CKERROR LoadData(CKStateChunk* statechunk, CKFileData::ShallowDocument* doc);
virtual CKStateChunk* SaveData(CKFileData::ShallowDocument* doc);
virtual CKERROR LoadData(CKStateChunk* statechunk, CKFileDocument* doc);
virtual CKStateChunk* SaveData(CKFileDocument* doc);
private:

View File

@ -42,6 +42,11 @@ namespace LibCmo::CK2 {
std::filesystem::create_directory(m_TempFolder);
}
CKMinContext::~CKMinContext() {
// free all created objects
for (const auto& [key, value] : this->m_ObjectsList) {
delete value;
}
// todo: free all created managers
}

View File

@ -16,7 +16,7 @@ namespace LibCmo::CK2::CKObjectImplements {
}
CKERROR CKObject::Load(CKStateChunk* chunk, const CKFileData::ShallowDocument* doc) {
CKERROR CKObject::Load(CKStateChunk* chunk, const CKFileDocument* doc) {
if (chunk->SeekIdentifier(Identifiers::CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIDDEN)) {
EnumsHelper::FlagEnumRm(this->m_ObjectFlags,
{ CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE,
@ -45,7 +45,7 @@ namespace LibCmo::CK2::CKObjectImplements {
return CKERROR::CKERR_OK;
}
CKStateChunk* CKObject::Save(CKFileData::ShallowDocument* doc) {
CKStateChunk* CKObject::Save(const CKFileDocument* doc) {
return nullptr;
}

View File

@ -25,8 +25,8 @@ namespace LibCmo::CK2::CKObjectImplements {
void SetObjectFlags(CK_OBJECT_FLAGS flags) { this->m_ObjectFlags = flags; }
virtual CK_CLASSID GetClassID(void) { return CK_CLASSID::CKCID_OBJECT; }
virtual CKERROR Load(CKStateChunk* chunk, const CKFileData::ShallowDocument* doc);
virtual CKStateChunk* Save(CKFileData::ShallowDocument* doc);
virtual CKERROR Load(CKStateChunk* chunk, const CKFileDocument* doc);
virtual CKStateChunk* Save(const CKFileDocument* doc);
};
class CKSceneObject : public CKObject {

View File

@ -85,7 +85,7 @@ namespace LibCmo::CK2 {
if (EnsureReadSpace(static_cast<CKDWORD>(size))) {
std::memcpy(data, this->m_pData + this->m_Parser.m_CurrentPos, size);
} return CKERROR::CKERR_OUTOFMEMORY;
} else return CKERROR::CKERR_OUTOFMEMORY;
return CKERROR::CKERR_OK;
}
/*

View File

@ -96,7 +96,7 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>Level4</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
@ -113,7 +113,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
@ -134,7 +134,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>Level4</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
@ -153,7 +153,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>Level4</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>

View File

@ -29,11 +29,11 @@ namespace LibCmo::EncodingHelper {
int count, write_result;
//converter to CHAR
count = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
count = WideCharToMultiByte(codepage, 0, src, -1, NULL, 0, NULL, NULL);
if (count <= 0) return false;
dest.resize(count);
write_result = WideCharToMultiByte(CP_UTF8, 0, src, -1, dest.data(), count, NULL, NULL);
write_result = WideCharToMultiByte(codepage, 0, src, -1, dest.data(), count, NULL, NULL);
if (write_result <= 0) return false;
return true;
@ -50,7 +50,7 @@ namespace LibCmo::EncodingHelper {
if (wcount <= 0) return false;
dest.resize(wcount);
write_result = MultiByteToWideChar(CP_UTF8, 0, src, -1, dest.data(), wcount);
write_result = MultiByteToWideChar(codepage, 0, src, -1, dest.data(), wcount);
if (write_result <= 0) return false;
return true;
@ -71,9 +71,9 @@ namespace LibCmo::EncodingHelper {
#else
static constexpr const IconvInc = 16;
bool DoIconv(const char* enc_from, const char* enc_to,
std::string& str_from, std::string& str_to) {
static constexpr const size_t IconvInc = 16;
bool DoIconv(const char* enc_from, const char* enc_to, std::string& str_from, std::string& str_to) {
iconv_t cd;
char *inbuf = nullptr, *outbuf = nullptr;
size_t inbytesleft, outbytesleft, nchars, result_len;
@ -199,7 +199,7 @@ namespace LibCmo::EncodingHelper {
#else
static const char UTF8_SYMBOL[] = "UTF-8";
static constexpr const char UTF8_SYMBOL[] = "UTF-8";
ENCODING_TOKEN CreateEncodingToken(std::string& token_string) {
ENCODING_TOKEN token = new(std::nothrow) char[token_string.size() + 1];