2023-02-25 17:39:39 +08:00
|
|
|
#pragma once
|
|
|
|
|
2023-08-25 17:35:45 +08:00
|
|
|
#include "../VTAll.hpp"
|
|
|
|
|
|
|
|
namespace LibCmo::XContainer {
|
|
|
|
using XIntArray = XArray<CK2::CKINT>;
|
|
|
|
using XFileObjectsTable = XHashTable<CK2::CK_ID, CK2::CKINT>;
|
|
|
|
}
|
2023-02-25 17:39:39 +08:00
|
|
|
|
2023-02-26 21:48:03 +08:00
|
|
|
namespace LibCmo::CK2 {
|
2023-02-25 17:39:39 +08:00
|
|
|
|
|
|
|
class CKBufferParser {
|
|
|
|
private:
|
|
|
|
char* m_MemBegin;
|
|
|
|
size_t m_MemPos;
|
|
|
|
bool m_NeedManualFree;
|
|
|
|
size_t m_MemSize;
|
|
|
|
|
|
|
|
public:
|
2023-08-25 17:35:45 +08:00
|
|
|
CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) :
|
|
|
|
m_MemBegin(static_cast<char*>(ptr)),
|
|
|
|
m_MemPos(0u), m_MemSize(rsize),
|
|
|
|
m_NeedManualFree(need_manual_free) {
|
|
|
|
;
|
|
|
|
}
|
|
|
|
~CKBufferParser() {
|
|
|
|
if (this->m_NeedManualFree) delete[](this->m_MemBegin);
|
|
|
|
}
|
|
|
|
LIBCMO_DISABLE_COPY_MOVE(CKBufferParser);
|
2023-02-25 17:39:39 +08:00
|
|
|
|
2023-08-25 17:35:45 +08:00
|
|
|
const void* GetPtr(void) { return (this->m_MemBegin + m_MemPos); }
|
|
|
|
void Read(void* data, size_t data_size) {
|
2023-02-26 21:48:03 +08:00
|
|
|
std::memcpy(data, (this->m_MemBegin + m_MemPos), data_size);
|
2023-02-25 17:39:39 +08:00
|
|
|
this->m_MemPos += data_size;
|
|
|
|
}
|
2023-08-25 17:35:45 +08:00
|
|
|
void Write(const void* data, size_t data_size) {
|
2023-02-26 21:48:03 +08:00
|
|
|
std::memcpy((this->m_MemBegin + m_MemPos), data, data_size);
|
2023-02-25 17:39:39 +08:00
|
|
|
this->m_MemPos += data_size;
|
|
|
|
}
|
2023-08-25 17:35:45 +08:00
|
|
|
void* GetBase(void) { return this->m_MemBegin; }
|
|
|
|
size_t GetSize(void) { return this->m_MemSize; }
|
|
|
|
size_t GetCursor(void) { return this->m_MemPos; }
|
|
|
|
void MoveCursor(size_t off) { this->m_MemPos += off; }
|
|
|
|
void SetCursor(size_t off) { this->m_MemPos = off; }
|
2023-02-25 17:39:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#pragma pack(push)
|
|
|
|
#pragma pack(1)
|
|
|
|
struct CKRawFileInfo {
|
|
|
|
CKBYTE NeMo[8];
|
|
|
|
CKDWORD Crc;
|
|
|
|
CKDWORD CKVersion;
|
|
|
|
CKDWORD FileVersion;
|
|
|
|
CKDWORD Zero;
|
|
|
|
CKDWORD FileWriteMode;
|
|
|
|
CKDWORD Hdr1PackSize;
|
|
|
|
|
|
|
|
CKDWORD DataPackSize;
|
|
|
|
CKDWORD DataUnPackSize;
|
|
|
|
CKDWORD ManagerCount;
|
|
|
|
CKDWORD ObjectCount;
|
|
|
|
CKDWORD MaxIDSaved;
|
|
|
|
CKDWORD ProductVersion;
|
|
|
|
CKDWORD ProductBuild;
|
|
|
|
CKDWORD Hdr1UnPackSize;
|
|
|
|
};
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
class CKFileInfo {
|
|
|
|
public:
|
2023-08-25 17:35:45 +08:00
|
|
|
CKFileInfo() :
|
|
|
|
ProductVersion(0u), ProductBuild(0x01010000u), FileWriteMode(CK_FILE_WRITEMODE::CKFILE_UNCOMPRESSED),
|
|
|
|
FileVersion(8u), CKVersion(CKVERSION), FileSize(0u),
|
|
|
|
ObjectCount(0u), ManagerCount(0u), MaxIDSaved(0u), Crc(0u),
|
|
|
|
Hdr1PackSize(0u), Hdr1UnPackSize(0u), DataPackSize(0u), DataUnPackSize(0u) {}
|
|
|
|
~CKFileInfo() {}
|
|
|
|
LIBCMO_DEFAULT_COPY_MOVE(CKFileInfo);
|
|
|
|
|
|
|
|
CKDWORD ProductVersion; ///< Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION)
|
|
|
|
CKDWORD ProductBuild; ///< Virtools Build Number.
|
|
|
|
CK_FILE_WRITEMODE FileWriteMode; ///< Options used to save this file. (CK_FILE_WRITEMODE)
|
|
|
|
CKDWORD FileVersion; ///< Version of file format when file was saved.
|
|
|
|
CKDWORD CKVersion; ///< Version of CK when file was saved.
|
|
|
|
CKDWORD FileSize; ///< Size of file in bytes.
|
|
|
|
CKDWORD ObjectCount; ///< Number of objects stored in the file.
|
|
|
|
CKDWORD ManagerCount; ///< Number of managers which saved data in the file.
|
|
|
|
CKDWORD MaxIDSaved; ///< Maximum Object identifier saved
|
|
|
|
CKDWORD Crc; ///< Crc of data
|
|
|
|
CKDWORD Hdr1PackSize; ///< Reserved
|
|
|
|
CKDWORD Hdr1UnPackSize; ///< Reserved
|
|
|
|
CKDWORD DataPackSize; ///< Reserved
|
|
|
|
CKDWORD DataUnPackSize; ///< Reserved
|
2023-02-25 17:39:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class CKFileObject {
|
|
|
|
public:
|
|
|
|
CKFileObject();
|
2023-02-28 14:04:38 +08:00
|
|
|
CKFileObject(const CKFileObject&);
|
2023-08-25 17:35:45 +08:00
|
|
|
CKFileObject(CKFileObject&&);
|
2023-02-28 14:04:38 +08:00
|
|
|
CKFileObject& operator=(const CKFileObject&);
|
2023-08-25 17:35:45 +08:00
|
|
|
CKFileObject& operator=(CKFileObject&&);
|
2023-02-25 17:39:39 +08:00
|
|
|
~CKFileObject();
|
|
|
|
|
2023-08-25 17:35:45 +08:00
|
|
|
CK_ID ObjectId; ///< ID of the object being load/saved (as it will be/was saved in the file)
|
|
|
|
CK_ID CreatedObjectId; ///< ID of the object being created
|
|
|
|
CK_CLASSID ObjectCid; ///< Class Identifier of the object
|
|
|
|
CKObject* ObjPtr; ///< A pointer to the object itself (as CreatedObject when loading)
|
|
|
|
TypeHelper::MKString Name; ///< Name of the Object
|
|
|
|
CKStateChunk* Data; ///< A CKStateChunk that contains object information
|
|
|
|
//CKINT PostPackSize; ///< When compressed chunk by chunk : size of Data after compression
|
|
|
|
//CKINT PrePackSize; ///< When compressed chunk by chunk : size of Data before compression
|
|
|
|
CK_FO_OPTIONS Options; ///< When loading an object it may be renamed , use to replace another object
|
|
|
|
CKINT FileIndex; ///< Position of the object data inside uncompressed file buffer
|
|
|
|
CKDWORD SaveFlags; ///< Flags used when this object was saved.
|
2023-02-25 17:39:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class CKFileManagerData {
|
|
|
|
public:
|
|
|
|
CKFileManagerData();
|
2023-02-28 14:04:38 +08:00
|
|
|
CKFileManagerData(const CKFileManagerData&);
|
2023-08-25 17:35:45 +08:00
|
|
|
CKFileManagerData(CKFileManagerData&&);
|
2023-02-28 14:04:38 +08:00
|
|
|
CKFileManagerData& operator=(const CKFileManagerData&);
|
2023-08-25 17:35:45 +08:00
|
|
|
CKFileManagerData& operator=(CKFileManagerData&&);
|
2023-02-25 17:39:39 +08:00
|
|
|
~CKFileManagerData();
|
|
|
|
|
|
|
|
CKStateChunk* Data;
|
|
|
|
CKGUID Manager;
|
|
|
|
};
|
|
|
|
|
|
|
|
class CKFilePluginDependencies {
|
|
|
|
public:
|
2023-08-25 17:35:45 +08:00
|
|
|
CKFilePluginDependencies() :
|
|
|
|
m_PluginCategory(CK_PLUGIN_TYPE::CKPLUGIN_MANAGER_DLL), m_Guids() {}
|
|
|
|
~CKFilePluginDependencies() {}
|
|
|
|
LIBCMO_DEFAULT_COPY_MOVE(CKFilePluginDependencies);
|
2023-02-25 17:39:39 +08:00
|
|
|
|
|
|
|
CK_PLUGIN_TYPE m_PluginCategory;
|
2023-08-25 17:35:45 +08:00
|
|
|
XContainer::XArray<CKGUID> m_Guids;
|
|
|
|
XContainer::XBitArray ValidGuids;
|
2023-03-03 11:06:26 +08:00
|
|
|
};
|
2023-02-25 17:39:39 +08:00
|
|
|
|
2023-08-25 17:35:45 +08:00
|
|
|
/**
|
|
|
|
@brief CKFile provides functions to save/load files in Virtools format.
|
|
|
|
@remark
|
|
|
|
+ Use CKFile just like a normal C++ class with passing CKCotext pointer.
|
|
|
|
+ Once created a CKFile can be used to save one or more objects to disk.
|
|
|
|
+ Only can load objects when this CKFile is empty. Use ClearData() to clear any existed CKFile.
|
|
|
|
+ In any case, CKFile can run Save(). So you can create a CKFile, add some obejcts and save it.
|
|
|
|
Or you can load a file by CKFile and add/modify something then save it.
|
|
|
|
*/
|
2023-02-25 17:39:39 +08:00
|
|
|
class CKFile {
|
|
|
|
public:
|
2023-08-25 17:35:45 +08:00
|
|
|
CKFile(CKContext* ctx);
|
2023-02-25 17:39:39 +08:00
|
|
|
~CKFile();
|
2023-08-25 17:35:45 +08:00
|
|
|
LIBCMO_DISABLE_COPY_MOVE(CKFile);
|
2023-02-25 17:39:39 +08:00
|
|
|
|
2023-08-25 17:35:45 +08:00
|
|
|
// ========== Reset CKFile ==========
|
2023-02-25 17:39:39 +08:00
|
|
|
void ClearData(void);
|
|
|
|
|
2023-08-25 17:35:45 +08:00
|
|
|
// ========== Loading ==========
|
|
|
|
CKERROR ShallowLoad(CKSTRING u8_filename);
|
|
|
|
CKERROR DeepLoad(CKSTRING u8_filename);
|
2023-02-25 17:39:39 +08:00
|
|
|
|
2023-08-25 17:35:45 +08:00
|
|
|
// ========== Loading Result ==========
|
|
|
|
const XContainer::XArray<CKFileObject>& GetFileObjects();
|
|
|
|
const XContainer::XArray<XContainer::XString>& GetIncludedFiles();
|
|
|
|
|
|
|
|
// ========== Saving Preparing ==========
|
|
|
|
CKBOOL AddSavedObject(CKObject* obj, CKDWORD flags = CK_STATESAVE_ALL);
|
|
|
|
CKBOOL AddSavedObjects(CKObjectArray* objarray, CKDWORD flags = CK_STATESAVE_ALL);
|
|
|
|
CKBOOL AddSavedFile(CKSTRING u8FileName);
|
|
|
|
|
|
|
|
// ========== Saving ==========
|
|
|
|
CKERROR Save(CKSTRING u8_filename);
|
2023-02-25 17:39:39 +08:00
|
|
|
|
|
|
|
//CKERROR Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags);
|
|
|
|
//CKERROR OpenFile(CKSTRING u8_filename, CK_LOAD_FLAGS flags);
|
|
|
|
//CKERROR OpenMemory(void* MemoryBuffer, size_t BufferSize, CK_LOAD_FLAGS Flags);
|
|
|
|
//CKERROR ReadFileHeaders(CKBufferParser** ParserPtr);
|
|
|
|
//CKERROR ReadFileData(CKBufferParser** ParserPtr);
|
|
|
|
//CKERROR LoadFileData(void/*CKObjectArray list*/);
|
|
|
|
//CKERROR FinishLoading(/*CKObjectArray list, */CK_LOAD_FLAGS flags);
|
|
|
|
|
2023-08-25 17:35:45 +08:00
|
|
|
CKINT m_SaveIDMax; // Maximum CK_ID found when saving or loading objects
|
|
|
|
XContainer::XArray<CKFileObject> m_FileObjects; // List of objects being saved / loaded
|
|
|
|
XContainer::XArray<CKFileManagerData> m_ManagersData; // Manager Data loaded
|
|
|
|
XContainer::XArray<CKFilePluginDependencies> m_PluginsDep; // Plugins dependencies for this file
|
|
|
|
// XContainer::XClassArray<XContainer::XIntArray> m_IndexByClassId; // List of index in the m_FileObjects table sorted by ClassID
|
|
|
|
XContainer::XArray<XContainer::XString> m_IncludedFiles; // List of files that should be inserted in the CMO file.
|
|
|
|
CKFileInfo m_FileInfo; // Headers summary
|
|
|
|
|
|
|
|
//XContainer::XFileObjectsTable m_ObjectsHashTable;
|
|
|
|
//CKBOOL m_ReadFileDataDone;
|
|
|
|
//CKBOOL m_SceneSaved;
|
|
|
|
//XContainer::XIntArray m_DuplicateNameFounds; // A List of file object index for which a existing object with the same name has been
|
|
|
|
// // found, this list is build if the load option contains CK_LOAD_AUTOMATICMODE or CK_LOAD_DODIALOG
|
|
|
|
//XContainer::XBitArray m_AlreadySavedMask; // BitArray of IDs already saved {secret}
|
|
|
|
//XContainer::XBitArray m_AlreadyReferencedMask; // BitArray of IDs already referenced {secret}
|
|
|
|
//XContainer::XObjectPointerArray m_ReferencedObjects;
|
2023-02-25 17:39:39 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
// reader function and variables
|
2023-08-25 17:35:45 +08:00
|
|
|
CKERROR ReadFileHeader(CKBufferParser* ParserPtr);
|
|
|
|
CKERROR ReadFileData(CKBufferParser* ParserPtr);
|
2023-02-25 17:39:39 +08:00
|
|
|
|
|
|
|
// writer function and varibales
|
|
|
|
|
|
|
|
// shared function and variables
|
2023-08-25 17:35:45 +08:00
|
|
|
bool mCanLoad;
|
|
|
|
CKContext* m_Ctx;
|
2023-02-25 17:39:39 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|