ready for file saving dev

This commit is contained in:
yyc12345 2023-08-28 14:18:58 +08:00
parent 76be4dd8d2
commit f0657b1656
6 changed files with 159 additions and 10 deletions

View File

@ -93,10 +93,47 @@ namespace LibCmo::CK2 {
#pragma endregion #pragma endregion
#pragma region Common Manager Functions
CKINT CKContext::GetManagerCount() {
return 0;
}
MgrImpls::CKBaseManager* CKContext::GetManager(int index) {
return nullptr;
}
#pragma endregion
#pragma region File Save/Load Options
void CKContext::SetCompressionLevel(CKINT level) {
if (level > 0 && level < 10) {
m_CompressionLevel = level;
}
}
CKINT CKContext::GetCompressionLevel() {
return m_CompressionLevel;
}
void CKContext::SetFileWriteMode(CK_FILE_WRITEMODE mode) {
m_FileWriteMode = mode;
}
CK_FILE_WRITEMODE CKContext::GetFileWriteMode() {
return m_FileWriteMode;
}
#pragma endregion
#pragma region Ctor Dtor #pragma region Ctor Dtor
CKContext::CKContext() : CKContext::CKContext() :
m_ObjectsList(), m_ReturnedObjectIds(), m_ObjectsList(), m_ReturnedObjectIds(),
m_CompressionLevel(5), m_FileWriteMode(CK_FILE_WRITEMODE::CKFILE_UNCOMPRESSED),
m_NameEncoding(), m_TempFolder(), m_NameEncoding(), m_TempFolder(),
m_OutputCallback(nullptr) m_OutputCallback(nullptr)
{ {

View File

@ -57,6 +57,19 @@ namespace LibCmo::CK2 {
//CKINT GetObjectsCountByClassID(CK_CLASSID cid); //CKINT GetObjectsCountByClassID(CK_CLASSID cid);
//CK_ID* GetObjectsListByClassID(CK_CLASSID cid); //CK_ID* GetObjectsListByClassID(CK_CLASSID cid);
// ========== Common Managers Functions ==========
CKINT GetManagerCount();
MgrImpls::CKBaseManager* GetManager(int index);
// ========== File Save/Load Options ==========
void SetCompressionLevel(CKINT level);
CKINT GetCompressionLevel();
void SetFileWriteMode(CK_FILE_WRITEMODE mode);
CK_FILE_WRITEMODE GetFileWriteMode();
// ========== Encoding utilities ========== // ========== Encoding utilities ==========
void GetUtf8String(const std::string& native_name, std::string& u8_name); void GetUtf8String(const std::string& native_name, std::string& u8_name);
@ -81,6 +94,10 @@ namespace LibCmo::CK2 {
XContainer::XArray<ObjImpls::CKObject*> m_ObjectsList; XContainer::XArray<ObjImpls::CKObject*> m_ObjectsList;
std::deque<CK_ID> m_ReturnedObjectIds; std::deque<CK_ID> m_ReturnedObjectIds;
// ========== File Save/Load Options ==========
CKINT m_CompressionLevel;
CK_FILE_WRITEMODE m_FileWriteMode;
// ========== Encoding utilities ========== // ========== Encoding utilities ==========
std::vector<EncodingHelper::ENCODING_TOKEN> m_NameEncoding; std::vector<EncodingHelper::ENCODING_TOKEN> m_NameEncoding;

View File

@ -17,12 +17,26 @@ namespace LibCmo::CK2 {
size_t m_MemSize; size_t m_MemSize;
public: public:
/**
* @brief Create CKBufferParser from a existed buffer.
* @param ptr The start pointer of buffer. This buffer should be allocated by 'new[]', not 'new' or 'malloc()'.
* @param rsize The size of buffer.
* @param need_manual_free True if provided buffer need freed by CKBufferParser automatically.
*/
CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) : CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) :
m_MemBegin(static_cast<char*>(ptr)), m_MemBegin(static_cast<char*>(ptr)),
m_MemPos(0u), m_MemSize(rsize), m_MemPos(0u), m_MemSize(rsize),
m_NeedManualFree(need_manual_free) { m_NeedManualFree(need_manual_free)
; {}
} /**
* @brief Create CKBufferParser from a new created buffer.
* @param newsize The size of new buffer.
*/
CKBufferParser(size_t newsize) :
m_MemBegin(new char[newsize]),
m_MemPos(0u), m_MemSize(newsize),
m_NeedManualFree(true)
{}
~CKBufferParser() { ~CKBufferParser() {
if (this->m_NeedManualFree) delete[](this->m_MemBegin); if (this->m_NeedManualFree) delete[](this->m_MemBegin);
} }
@ -209,6 +223,22 @@ namespace LibCmo::CK2 {
CKERROR Save(CKSTRING u8_filename); CKERROR Save(CKSTRING u8_filename);
protected: protected:
CKBOOL m_Done;
/**
* True if this writer is copy from reader.
* The data copied from reader mean that calling just only do some small modification.
* So we don't need try getting some managers or save file options from CKContext.
* Just apply the data coming from reader.
* Also, Add object functions is not allowed when writer copying from reader.
*/
CKBOOL m_IsCopyFromReader;
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::XArray<XContainer::XString> m_IncludedFiles; /**< List of files that should be inserted in the CMO file. */
CKFileInfo m_FileInfo; /**< Headers summary */
CKContext* m_Ctx; CKContext* m_Ctx;
CKFileVisitor m_Visitor; CKFileVisitor m_Visitor;
}; };

View File

@ -13,12 +13,12 @@ namespace LibCmo::CK2 {
CKFileObject::CKFileObject() : CKFileObject::CKFileObject() :
ObjectId(0u), CreatedObjectId(0u), ObjectCid(CK_CLASSID::CKCID_OBJECT), ObjectId(0u), CreatedObjectId(0u), ObjectCid(CK_CLASSID::CKCID_OBJECT),
ObjPtr(nullptr), Name(), Data(nullptr), Options(CK_FO_OPTIONS::CK_FO_DEFAULT), ObjPtr(nullptr), Name(), Data(nullptr), Options(CK_FO_OPTIONS::CK_FO_DEFAULT),
FileIndex(0u), SaveFlags(0u) {} FileIndex(0u), SaveFlags(CK_STATESAVE_ALL) {}
CKFileObject::CKFileObject(const CKFileObject& rhs) : CKFileObject::CKFileObject(const CKFileObject& rhs) :
ObjectId(rhs.ObjectId), CreatedObjectId(rhs.CreatedObjectId), ObjectCid(rhs.ObjectCid), ObjectId(rhs.ObjectId), CreatedObjectId(rhs.CreatedObjectId), ObjectCid(rhs.ObjectCid),
ObjPtr(rhs.ObjPtr), Name(rhs.Name), Data(rhs.Data), Options(rhs.Options), ObjPtr(rhs.ObjPtr), Name(rhs.Name), Data(rhs.Data), Options(rhs.Options),
FileIndex(rhs.FileIndex), SaveFlags(0u) { FileIndex(rhs.FileIndex), SaveFlags(rhs.SaveFlags) {
if (this->Data != nullptr) { if (this->Data != nullptr) {
this->Data = new CKStateChunk(*(rhs.Data)); this->Data = new CKStateChunk(*(rhs.Data));
} }
@ -27,7 +27,7 @@ namespace LibCmo::CK2 {
CKFileObject::CKFileObject(CKFileObject&& rhs) : CKFileObject::CKFileObject(CKFileObject&& rhs) :
ObjectId(rhs.ObjectId), CreatedObjectId(rhs.CreatedObjectId), ObjectCid(rhs.ObjectCid), ObjectId(rhs.ObjectId), CreatedObjectId(rhs.CreatedObjectId), ObjectCid(rhs.ObjectCid),
ObjPtr(rhs.ObjPtr), Name(rhs.Name), Data(rhs.Data), Options(rhs.Options), ObjPtr(rhs.ObjPtr), Name(rhs.Name), Data(rhs.Data), Options(rhs.Options),
FileIndex(rhs.FileIndex), SaveFlags(0u) { FileIndex(rhs.FileIndex), SaveFlags(rhs.SaveFlags) {
rhs.Data = nullptr; rhs.Data = nullptr;
} }
@ -158,22 +158,81 @@ namespace LibCmo::CK2 {
#pragma region CKFileWriter #pragma region CKFileWriter
CKFileWriter::CKFileWriter(CKContext* ctx) : CKFileWriter::CKFileWriter(CKContext* ctx) :
m_Ctx(ctx), m_Visitor(this) {} m_Ctx(ctx), m_Visitor(this),
m_Done(false), m_IsCopyFromReader(false),
m_FileObjects(), m_ManagersData(), m_PluginsDep(), m_IncludedFiles(),
m_FileInfo()
{}
CKFileWriter::CKFileWriter(CKContext* ctx, CKFileReader* reader) : CKFileWriter::CKFileWriter(CKContext* ctx, CKFileReader* reader) :
m_Ctx(ctx), m_Visitor(this) {} m_Ctx(ctx), m_Visitor(this),
m_Done(false), m_IsCopyFromReader(true),
m_FileObjects(), m_ManagersData(), m_PluginsDep(), m_IncludedFiles(),
m_FileInfo()
{
// copy objects
for (const auto& item : reader->GetFileObjects()) {
CKFileObject obj;
// copy CKObject pointer
obj.ObjPtr = item.ObjPtr;
// and use ctor to copy CKStateChunk
if (item.Data == nullptr) {
obj.Data = nullptr;
} else {
obj.Data = new CKStateChunk(*item.Data);
}
// copy save flag
obj.SaveFlags = item.SaveFlags;
// insert
m_FileObjects.emplace_back(std::move(obj));
}
// copy managers
for (const auto& item : reader->GetManagersData()) {
CKFileManagerData mgr;
// copy guid
mgr.Manager = item.Manager;
// copy chunk
if (item.Data == nullptr) {
mgr.Data = nullptr;
} else {
mgr.Data = new CKStateChunk(*item.Data);
}
// insert
m_ManagersData.emplace_back(std::move(mgr));
}
// copy plugin dep
for (const auto& item : reader->GetPluginsDep()) {
// direct copy
m_PluginsDep.emplace_back(item);
}
// copy included file
for (const auto& item : reader->GetIncludedFiles()) {
// direct copy
m_IncludedFiles.emplace_back(item);
}
}
CKFileWriter::~CKFileWriter() {} CKFileWriter::~CKFileWriter() {}
CKBOOL CKFileWriter::AddSavedObject(ObjImpls::CKObject* obj, CKDWORD flags) { CKBOOL CKFileWriter::AddSavedObject(ObjImpls::CKObject* obj, CKDWORD flags) {
if (m_Done || m_IsCopyFromReader) return CKFALSE;
return CKFALSE; return CKFALSE;
} }
CKBOOL CKFileWriter::AddSavedObjects(CKObjectArray* objarray, CKDWORD flags) { CKBOOL CKFileWriter::AddSavedObjects(CKObjectArray* objarray, CKDWORD flags) {
if (m_Done || m_IsCopyFromReader) return CKFALSE;
return CKFALSE; return CKFALSE;
} }
CKBOOL CKFileWriter::AddSavedFile(CKSTRING u8FileName) { CKBOOL CKFileWriter::AddSavedFile(CKSTRING u8FileName) {
if (m_Done || m_IsCopyFromReader) return CKFALSE;
return CKFALSE; return CKFALSE;
} }

View File

@ -155,11 +155,12 @@ namespace LibCmo::CK2 {
CKBOOL CKIsChildClassOf(CK_CLASSID child, CK_CLASSID parent) { CKBOOL CKIsChildClassOf(CK_CLASSID child, CK_CLASSID parent) {
// get corresponding index first // get corresponding index first
// if we can't find it, return false anyway.
auto finder = g_CKClassInfoId2Idx.find(child); auto finder = g_CKClassInfoId2Idx.find(child);
if (finder == g_CKClassInfoId2Idx.end()) LIBPANIC("No such CK_CLASSID."); if (finder == g_CKClassInfoId2Idx.end()) return CKFALSE;
size_t child_idx = finder->second; size_t child_idx = finder->second;
finder = g_CKClassInfoId2Idx.find(parent); finder = g_CKClassInfoId2Idx.find(parent);
if (finder == g_CKClassInfoId2Idx.end()) LIBPANIC("No such CK_CLASSID."); if (finder == g_CKClassInfoId2Idx.end()) return CKFALSE;
size_t parent_idx = finder->second; size_t parent_idx = finder->second;
return g_CKClassInfo[child_idx].Parents[parent_idx]; return g_CKClassInfo[child_idx].Parents[parent_idx];

View File

@ -119,6 +119,11 @@ namespace LibCmo {
const char* c_str() const { const char* c_str() const {
return m_HasStr ? m_Str.c_str() : nullptr; return m_HasStr ? m_Str.c_str() : nullptr;
} }
const size_t size() const {
return m_HasStr ? m_Str.size() : 0u;
}
private: private:
bool m_HasStr; bool m_HasStr;
std::string m_Str; std::string m_Str;