fix including file error in CKFile. update reader -> writer method

This commit is contained in:
yyc12345 2023-09-30 14:24:37 +08:00
parent eedd9bdb55
commit abea66d6f0
8 changed files with 153 additions and 85 deletions

View File

@ -107,7 +107,7 @@ namespace LibCmo::CK2 {
CKDWORD FileSize; /**< Size of file in bytes. */ CKDWORD FileSize; /**< Size of file in bytes. */
CKDWORD ObjectCount; /**< Number of objects stored in the file. */ CKDWORD ObjectCount; /**< Number of objects stored in the file. */
CKDWORD ManagerCount; /**< Number of managers which saved data in the file. */ CKDWORD ManagerCount; /**< Number of managers which saved data in the file. */
CKDWORD MaxIDSaved; /**< Maximum Object identifier saved */ CK_ID MaxIDSaved; /**< Maximum Object identifier saved */
CKDWORD Crc; /**< Crc of data */ CKDWORD Crc; /**< Crc of data */
CKDWORD Hdr1PackSize; /**< The compressed size of Header section. */ CKDWORD Hdr1PackSize; /**< The compressed size of Header section. */
CKDWORD Hdr1UnPackSize; /**< The uncompressed size of Header section. */ CKDWORD Hdr1UnPackSize; /**< The uncompressed size of Header section. */
@ -195,7 +195,7 @@ namespace LibCmo::CK2 {
CKERROR DeepLoad(CKSTRING u8_filename); CKERROR DeepLoad(CKSTRING u8_filename);
// ========== Loading Result ========== // ========== Loading Result ==========
CKINT GetSaveIdMax(); CK_ID GetSaveIdMax();
const XContainer::XArray<CKFileObject>& GetFileObjects(); const XContainer::XArray<CKFileObject>& GetFileObjects();
const XContainer::XArray<CKFileManagerData>& GetManagersData(); const XContainer::XArray<CKFileManagerData>& GetManagersData();
const XContainer::XArray<CKFilePluginDependencies>& GetPluginsDep(); const XContainer::XArray<CKFilePluginDependencies>& GetPluginsDep();
@ -204,12 +204,16 @@ namespace LibCmo::CK2 {
protected: protected:
bool m_Done; bool m_Done;
CKINT m_SaveIDMax; /**< Maximum CK_ID found when saving or loading objects */ CK_ID m_SaveIDMax; /**< Maximum CK_ID found when saving or loading objects */
XContainer::XArray<CKFileObject> m_FileObjects; /**< List of objects being saved / loaded */ XContainer::XArray<CKFileObject> m_FileObjects; /**< List of objects being saved / loaded */
XContainer::XArray<CKFileManagerData> m_ManagersData; /**< Manager Data loaded */ XContainer::XArray<CKFileManagerData> m_ManagersData; /**< Manager Data loaded */
XContainer::XArray<CKFilePluginDependencies> m_PluginsDep; /**< Plugins dependencies for this file */ 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::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. */ /**
* @brief List of files that should be inserted in the CMO file.
* @remark Each item is just file name, not the full path to file.
*/
XContainer::XArray<XContainer::XString> m_IncludedFiles;
CKFileInfo m_FileInfo; /**< Headers summary */ CKFileInfo m_FileInfo; /**< Headers summary */
CKERROR ReadFileHeader(CKBufferParser* ParserPtr); CKERROR ReadFileHeader(CKBufferParser* ParserPtr);
@ -223,7 +227,7 @@ namespace LibCmo::CK2 {
friend class CKFileVisitor; friend class CKFileVisitor;
public: public:
CKFileWriter(CKContext* ctx); CKFileWriter(CKContext* ctx);
CKFileWriter(CKContext* ctx, CKFileReader* reader); CKFileWriter(CKContext* ctx, CKFileReader* reader, bool is_shallow);
~CKFileWriter(); ~CKFileWriter();
LIBCMO_DISABLE_COPY_MOVE(CKFileWriter); LIBCMO_DISABLE_COPY_MOVE(CKFileWriter);
@ -238,19 +242,29 @@ namespace LibCmo::CK2 {
protected: protected:
bool m_Done; bool m_Done;
/** /**
* True if this writer is copy from reader. * @brief True if this writer is not allowed to add objects.
* The data copied from reader mean that calling just only do some small modification. * @remark
* So we don't need try getting some managers or save file options from CKContext. * + This field should be false in default.
* Just apply the data coming from reader. * + This field usually be set when importing from reader.
* Also, Add object functions is not allowed when writer copying from reader.
*/ */
bool m_IsCopyFromReader; bool m_DisableAddingObject;
/**
* @brief True if this writer is not allowed to add files.
* @remark
* + This field should be false in default.
* + This field usually be set when importing from reader.
*/
bool m_DisableAddingFile;
CKINT m_SaveIDMax; /**< Maximum CK_ID found when saving or loading objects */ CK_ID m_SaveIDMax; /**< Maximum CK_ID found when saving or loading objects */
XContainer::XArray<CKFileObject> m_FileObjects; /**< List of objects being saved / loaded */ XContainer::XArray<CKFileObject> m_FileObjects; /**< List of objects being saved / loaded */
XContainer::XArray<CKFileManagerData> m_ManagersData; /**< Manager Data loaded */ XContainer::XArray<CKFileManagerData> m_ManagersData; /**< Manager Data loaded */
XContainer::XArray<CKFilePluginDependencies> m_PluginsDep; /**< Plugins dependencies for this file */ 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. */ /**
* @brief List of files that should be inserted in the CMO file.
* @remark Each item is the full path to file.
*/
XContainer::XArray<XContainer::XString> m_IncludedFiles;
XContainer::XHashTable<CK_ID, CKDWORD> m_ObjectsHashTable; /**< A Object ID to save index hash table. */ XContainer::XHashTable<CK_ID, CKDWORD> m_ObjectsHashTable; /**< A Object ID to save index hash table. */
XContainer::XBitArray m_AlreadySavedMask; /**< Field recording saved object id. If this object is saved, set m_AlreadySavedMask[id] to true. Also used to check whether object already is in save list. */ XContainer::XBitArray m_AlreadySavedMask; /**< Field recording saved object id. If this object is saved, set m_AlreadySavedMask[id] to true. Also used to check whether object already is in save list. */
CKFileInfo m_FileInfo; /**< Headers summary */ CKFileInfo m_FileInfo; /**< Headers summary */

View File

@ -1,5 +1,7 @@
#include "CKFile.hpp" #include "CKFile.hpp"
#include "CKStateChunk.hpp" #include "CKStateChunk.hpp"
#include "CKContext.hpp"
#include "MgrImpls/CKPathManager.hpp"
#include "ObjImpls/CKObject.hpp" #include "ObjImpls/CKObject.hpp"
#include <cstdarg> #include <cstdarg>
@ -132,7 +134,7 @@ namespace LibCmo::CK2 {
CKFileReader::~CKFileReader() {} CKFileReader::~CKFileReader() {}
CKINT CKFileReader::GetSaveIdMax() { CK_ID CKFileReader::GetSaveIdMax() {
return m_SaveIDMax; return m_SaveIDMax;
} }
@ -162,78 +164,124 @@ namespace LibCmo::CK2 {
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_Done(false),
m_DisableAddingObject(false), m_DisableAddingFile(false),
m_SaveIDMax(0), m_SaveIDMax(0),
m_FileObjects(), m_ManagersData(), m_PluginsDep(), m_IncludedFiles(), m_FileObjects(), m_ManagersData(), m_PluginsDep(), m_IncludedFiles(),
m_FileInfo() m_FileInfo()
{} {}
CKFileWriter::CKFileWriter(CKContext* ctx, CKFileReader* reader) : CKFileWriter::CKFileWriter(CKContext* ctx, CKFileReader* reader, bool is_shallow) :
m_Ctx(ctx), m_Visitor(this), m_Ctx(ctx), m_Visitor(this),
m_Done(false), m_IsCopyFromReader(true), m_Done(false),
m_DisableAddingObject(true), m_DisableAddingFile(!is_shallow), // only disable adding file in shallow mode. but disable adding object in all mode.
m_SaveIDMax(0), m_SaveIDMax(0),
m_FileObjects(), m_ManagersData(), m_PluginsDep(), m_IncludedFiles(), m_FileObjects(), m_ManagersData(), m_PluginsDep(), m_IncludedFiles(),
m_FileInfo() m_FileInfo()
{ {
// sync save id max if (is_shallow) {
this->m_SaveIDMax = reader->GetSaveIdMax();
// copy objects #pragma region Shallow Assign
for (const auto& item : reader->GetFileObjects()) {
CKFileObject obj; // sync save id max
// copy CKObject pointer this->m_SaveIDMax = reader->GetSaveIdMax();
obj.ObjPtr = item.ObjPtr;
// and use ctor to copy CKStateChunk // copy statechunk
if (item.Data == nullptr) { for (const auto& item : reader->GetFileObjects()) {
obj.Data = nullptr; CKFileObject obj;
} else {
obj.Data = new CKStateChunk(*item.Data); // use ctor to copy CKStateChunk
if (item.Data == nullptr) {
obj.Data = nullptr;
} else {
obj.Data = new CKStateChunk(*item.Data);
}
// set other data
obj.ObjectId = item.ObjectId;
obj.CreatedObjectId = 0;
obj.ObjectCid = item.ObjectCid;
obj.ObjPtr = nullptr; // set zero for obj
obj.Name = item.Name;
obj.SaveFlags = item.SaveFlags;
// insert
m_FileObjects.emplace_back(std::move(obj));
} }
// copy other data // copy managers
obj.ObjectId = item.ObjectId; for (const auto& item : reader->GetManagersData()) {
obj.ObjectCid = item.ObjectCid; CKFileManagerData mgr;
obj.SaveFlags = item.SaveFlags; // copy guid
obj.Name = item.Name; mgr.Manager = item.Manager;
// copy chunk
if (item.Data == nullptr) {
mgr.Data = nullptr;
} else {
mgr.Data = new CKStateChunk(*item.Data);
}
// insert // insert
m_FileObjects.emplace_back(std::move(obj)); m_ManagersData.emplace_back(std::move(mgr));
}
// 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 // copy plugin dep
m_ManagersData.emplace_back(std::move(mgr)); for (const auto& item : reader->GetPluginsDep()) {
} // direct copy
m_PluginsDep.emplace_back(item);
}
// copy plugin dep // copy included file
for (const auto& item : reader->GetPluginsDep()) { for (const auto& item : reader->GetIncludedFiles()) {
// direct copy // resolve it to temp folder
m_PluginsDep.emplace_back(item); // and add it
} m_IncludedFiles.emplace_back(m_Ctx->GetPathManager()->GetTempFilePath(item.c_str()));
}
// copy included file #pragma endregion
for (const auto& item : reader->GetIncludedFiles()) {
// direct copy
m_IncludedFiles.emplace_back(item);
}
} else {
#pragma region Deep Assign
// copy object and calc max id
CK_ID maxid = 0;
for (const auto& item : reader->GetFileObjects()) {
CKFileObject obj;
// skip if invalid
if (item.ObjPtr == nullptr) continue;
// set obj ptr
obj.ObjPtr = item.ObjPtr;
// set other data
obj.ObjectId = obj.ObjPtr->GetID();
obj.ObjectCid = obj.ObjPtr->GetClassID();
obj.Data = nullptr; // blank statechunk
obj.SaveFlags = CK_STATESAVE_ALL;
XContainer::NSXString::FromCKSTRING(obj.Name, obj.ObjPtr->GetName());
// update max id
maxid = std::max(maxid, obj.ObjectId);
// insert
m_FileObjects.emplace_back(std::move(obj));
}
// set max id
m_SaveIDMax = maxid;
#pragma endregion
}
} }
CKFileWriter::~CKFileWriter() {} CKFileWriter::~CKFileWriter() {}
bool CKFileWriter::AddSavedObject(ObjImpls::CKObject* obj, CKDWORD flags) { bool CKFileWriter::AddSavedObject(ObjImpls::CKObject* obj, CKDWORD flags) {
if (m_Done || m_IsCopyFromReader) return false; if (m_Done || m_DisableAddingObject) return false;
if (obj == nullptr) return false; if (obj == nullptr) return false;
// check whether is saved. // check whether is saved.
@ -242,9 +290,11 @@ namespace LibCmo::CK2 {
// ok, insert this value // ok, insert this value
m_ObjectsHashTable.try_emplace(objid, static_cast<CKDWORD>(m_FileObjects.size())); m_ObjectsHashTable.try_emplace(objid, static_cast<CKDWORD>(m_FileObjects.size()));
XContainer::NSXBitArray::Set(m_AlreadySavedMask, static_cast<CKDWORD>(objid)); XContainer::NSXBitArray::Set(m_AlreadySavedMask, static_cast<CKDWORD>(objid));
// update max id
m_SaveIDMax = std::max(m_SaveIDMax, objid);
// add entry
CKFileObject fobj; CKFileObject fobj;
fobj.ObjectId = objid; fobj.ObjectId = objid;
fobj.ObjPtr = obj; fobj.ObjPtr = obj;
@ -257,7 +307,7 @@ namespace LibCmo::CK2 {
} }
bool CKFileWriter::AddSavedObjects(const XContainer::XObjectPointerArray& objarray, CKDWORD flags) { bool CKFileWriter::AddSavedObjects(const XContainer::XObjectPointerArray& objarray, CKDWORD flags) {
if (m_Done || m_IsCopyFromReader) return false; if (m_Done || m_DisableAddingObject) return false;
bool ret = true; bool ret = true;
for (auto obj : objarray) { for (auto obj : objarray) {
@ -270,7 +320,7 @@ namespace LibCmo::CK2 {
} }
bool CKFileWriter::AddSavedFile(CKSTRING u8FileName) { bool CKFileWriter::AddSavedFile(CKSTRING u8FileName) {
if (m_Done || m_IsCopyFromReader) return false; if (m_Done || m_DisableAddingFile) return false;
if (u8FileName == nullptr) return false; if (u8FileName == nullptr) return false;
m_IncludedFiles.emplace_back(u8FileName); m_IncludedFiles.emplace_back(u8FileName);

View File

@ -72,7 +72,7 @@ namespace LibCmo::CK2 {
this->m_FileInfo.FileSize = parser->GetSize(); this->m_FileInfo.FileSize = parser->GetSize();
this->m_FileInfo.ManagerCount = rawHeader.ManagerCount; this->m_FileInfo.ManagerCount = rawHeader.ManagerCount;
this->m_FileInfo.ObjectCount = rawHeader.ObjectCount; this->m_FileInfo.ObjectCount = rawHeader.ObjectCount;
this->m_FileInfo.MaxIDSaved = rawHeader.MaxIDSaved; this->m_FileInfo.MaxIDSaved = static_cast<CK_ID>(rawHeader.MaxIDSaved);
this->m_FileInfo.Hdr1PackSize = rawHeader.FileVersion >= 8 ? rawHeader.Hdr1PackSize : 0u; this->m_FileInfo.Hdr1PackSize = rawHeader.FileVersion >= 8 ? rawHeader.Hdr1PackSize : 0u;
this->m_FileInfo.Hdr1UnPackSize = rawHeader.FileVersion >= 8 ? rawHeader.Hdr1UnPackSize : 0u; this->m_FileInfo.Hdr1UnPackSize = rawHeader.FileVersion >= 8 ? rawHeader.Hdr1UnPackSize : 0u;
this->m_FileInfo.DataPackSize = rawHeader.DataPackSize; this->m_FileInfo.DataPackSize = rawHeader.DataPackSize;

View File

@ -46,8 +46,8 @@ namespace LibCmo::CK2 {
} }
// iterate manager // iterate manager
// if copied from reader. skip // if object adding is disabled, skip. because in that mode, no need to query manager data.
if (!m_IsCopyFromReader) { if (!m_DisableAddingObject) {
CKINT mgrcount = m_Ctx->GetManagerCount(); CKINT mgrcount = m_Ctx->GetManagerCount();
CKINT availablemgr = 0; CKINT availablemgr = 0;
@ -75,14 +75,11 @@ namespace LibCmo::CK2 {
} }
// if copied from reader, skip plugin dep // if object adding is disabled, skip plugin dep. same reason with manager iteration.
if (!m_IsCopyFromReader) { if (!m_DisableAddingObject) {
// todo: finish plugin dep filling // todo: finish plugin dep filling
} }
// MARK: skip include file filling.
// we order user manually fill it.
// ========== Size Calc ========== // ========== Size Calc ==========
// iterate 3 list to get each parts' size // iterate 3 list to get each parts' size
CKDWORD sumDataObjSize = 0, CKDWORD sumDataObjSize = 0,
@ -161,7 +158,7 @@ namespace LibCmo::CK2 {
rawHeader.DataPackSize = sumDataSize; rawHeader.DataPackSize = sumDataSize;
rawHeader.ProductVersion = DEVVERSION; rawHeader.ProductVersion = DEVVERSION;
rawHeader.ProductBuild = DEVBUILD; rawHeader.ProductBuild = DEVBUILD;
rawHeader.MaxIDSaved = m_SaveIDMax; rawHeader.MaxIDSaved = static_cast<CKDWORD>(m_SaveIDMax);
// crc will filled later // crc will filled later
// ========== Write header ========== // ========== Write header ==========
@ -289,7 +286,7 @@ namespace LibCmo::CK2 {
this->m_FileInfo.DataUnPackSize = rawHeader.DataUnPackSize; this->m_FileInfo.DataUnPackSize = rawHeader.DataUnPackSize;
this->m_FileInfo.ManagerCount = rawHeader.ManagerCount; this->m_FileInfo.ManagerCount = rawHeader.ManagerCount;
this->m_FileInfo.ObjectCount = rawHeader.ObjectCount; this->m_FileInfo.ObjectCount = rawHeader.ObjectCount;
this->m_FileInfo.MaxIDSaved = rawHeader.MaxIDSaved; this->m_FileInfo.MaxIDSaved = static_cast<CK_ID>(rawHeader.MaxIDSaved);
// fill file size and crc // fill file size and crc
this->m_FileInfo.FileSize = CKSizeof(CKRawFileInfo) + rawHeader.DataPackSize + rawHeader.Hdr1PackSize; this->m_FileInfo.FileSize = CKSizeof(CKRawFileInfo) + rawHeader.DataPackSize + rawHeader.Hdr1PackSize;
this->m_FileInfo.Crc = computedcrc; this->m_FileInfo.Crc = computedcrc;
@ -308,16 +305,19 @@ namespace LibCmo::CK2 {
datparser.reset(); datparser.reset();
// ========== Included Files ========== // ========== Included Files ==========
for (auto& fentry : m_IncludedFiles) { for (const auto& fentry : m_IncludedFiles) {
// get file name from full path
XContainer::XString filename(fentry);
m_Ctx->GetPathManager()->GetFileName(filename);
// write filename // write filename
m_Ctx->GetNativeString(fentry, name_conv); m_Ctx->GetNativeString(filename, name_conv);
CKDWORD filenamelen = static_cast<CKDWORD>(name_conv.size()); CKDWORD filenamelen = static_cast<CKDWORD>(name_conv.size());
std::fwrite(&filenamelen, sizeof(CKDWORD), 1, fs); std::fwrite(&filenamelen, sizeof(CKDWORD), 1, fs);
std::fwrite(name_conv.data(), sizeof(CKBYTE), filenamelen, fs); std::fwrite(name_conv.data(), sizeof(CKBYTE), filenamelen, fs);
// try mapping file. // try mapping file.
XContainer::XString tempfilename = m_Ctx->GetPathManager()->GetTempFilePath(fentry.c_str()); std::unique_ptr<VxMath::VxMemoryMappedFile> mappedFile(new VxMath::VxMemoryMappedFile(fentry.c_str()));
std::unique_ptr<VxMath::VxMemoryMappedFile> mappedFile(new VxMath::VxMemoryMappedFile(tempfilename.c_str()));
if (mappedFile->IsValid()) { if (mappedFile->IsValid()) {
// write file length // write file length
CKDWORD filebodylen = mappedFile->GetFileSize(); CKDWORD filebodylen = mappedFile->GetFileSize();
@ -331,7 +331,7 @@ namespace LibCmo::CK2 {
std::fwrite(&filebodylen, sizeof(CKDWORD), 1, fs); std::fwrite(&filebodylen, sizeof(CKDWORD), 1, fs);
// report error // report error
m_Ctx->OutputToConsoleEx("Fail to open temp file: %s", tempfilename.c_str()); m_Ctx->OutputToConsoleEx("Fail to open temp file: %" PRI_CKSTRING, fentry.c_str());
} }
// release mapped file // release mapped file

View File

@ -158,14 +158,14 @@ namespace LibCmo::CK2::ObjImpls {
// setup fake self // setup fake self
props.m_Size = CKSizeof(props); props.m_Size = CKSizeof(props);
props.m_Data = 6172; props.m_Data = 0;
// setup fake VxImageDescEx // setup fake VxImageDescEx
props.m_Format.Size = CKSizeof(props.m_Format); props.m_Format.Size = CKSizeof(props.m_Format);
props.m_Format.Flags = static_cast<CKDWORD>(VxMath::VX_PIXELFORMAT::_32_ARGB8888); props.m_Format.Flags = static_cast<CKDWORD>(VxMath::VX_PIXELFORMAT::_32_ARGB8888);
props.m_Format.Width = m_ImageHost.GetWidth(); props.m_Format.Width = m_ImageHost.GetWidth();
props.m_Format.Height = m_ImageHost.GetHeight(); props.m_Format.Height = m_ImageHost.GetHeight();
props.m_Format.BytesPerLine = VxMath::VxImageDescEx::PixelSize * props.m_Format.Height * props.m_Format.Width; props.m_Format.BytesPerLine = VxMath::VxImageDescEx::PixelSize * props.m_Format.Width;
props.m_Format.BitsPerPixel = 32; props.m_Format.BitsPerPixel = 32;
props.m_Format.RedMask = 0x00FF0000; props.m_Format.RedMask = 0x00FF0000;

View File

@ -399,7 +399,7 @@ namespace Unvirt::StructFormatter {
fputc('\n', stdout); fputc('\n', stdout);
fprintf(stdout, "Manager Count: %" PRIuCKDWORD "\nObject Count: %" PRIuCKDWORD "\nMax ID Saved: %" PRIuCKDWORD "\n", fprintf(stdout, "Manager Count: %" PRIuCKDWORD "\nObject Count: %" PRIuCKDWORD "\nMax ID Saved: %" PRIuCKID "\n",
fileinfo.ManagerCount, fileinfo.ObjectCount, fileinfo.MaxIDSaved fileinfo.ManagerCount, fileinfo.ObjectCount, fileinfo.MaxIDSaved
); );

View File

@ -9,7 +9,7 @@ namespace Unvirt::Context {
UnvirtContext::UnvirtContext() : UnvirtContext::UnvirtContext() :
m_Root(), m_Splitter(), m_Help(nullptr), m_Root(), m_Splitter(), m_Help(nullptr),
m_PageLen(10u), m_OrderExit(false), m_PageLen(10u), m_OrderExit(false),
m_Ctx(nullptr), m_FileReader(nullptr) { m_Ctx(nullptr), m_FileReader(nullptr), m_IsShallowRead(true) {
// create command root // create command root
CmdHelper::CommandRoot* root = &m_Root; CmdHelper::CommandRoot* root = &m_Root;
@ -175,6 +175,7 @@ namespace Unvirt::Context {
// delete reader // delete reader
delete m_FileReader; delete m_FileReader;
m_FileReader = nullptr; m_FileReader = nullptr;
m_IsShallowRead = true;
// clear context // clear context
m_Ctx->ClearAll(); m_Ctx->ClearAll();
} }
@ -242,8 +243,10 @@ namespace Unvirt::Context {
LibCmo::CK2::CKERROR err; LibCmo::CK2::CKERROR err;
if (is_deep) { if (is_deep) {
err = m_FileReader->DeepLoad(filepath.c_str()); err = m_FileReader->DeepLoad(filepath.c_str());
m_IsShallowRead = false;
} else { } else {
err = m_FileReader->ShallowLoad(filepath.c_str()); err = m_FileReader->ShallowLoad(filepath.c_str());
m_IsShallowRead = true;
} }
if (err != LibCmo::CK2::CKERROR::CKERR_OK) { if (err != LibCmo::CK2::CKERROR::CKERR_OK) {
// fail to load. release all. // fail to load. release all.
@ -277,7 +280,7 @@ namespace Unvirt::Context {
std::string filepath = *amap->Get<CmdHelper::StringArgument::vType>("filepath"); std::string filepath = *amap->Get<CmdHelper::StringArgument::vType>("filepath");
// construct writer from reader // construct writer from reader
LibCmo::CK2::CKFileWriter writer(m_Ctx, m_FileReader); LibCmo::CK2::CKFileWriter writer(m_Ctx, m_FileReader, m_IsShallowRead);
// backup current file write mode // backup current file write mode
// and replace it with reader // and replace it with reader

View File

@ -55,6 +55,7 @@ namespace Unvirt::Context {
bool m_OrderExit; bool m_OrderExit;
LibCmo::CK2::CKContext* m_Ctx; LibCmo::CK2::CKContext* m_Ctx;
LibCmo::CK2::CKFileReader* m_FileReader; LibCmo::CK2::CKFileReader* m_FileReader;
bool m_IsShallowRead;
}; };