update shit
This commit is contained in:
parent
427c9ee06f
commit
522660e65a
|
@ -169,7 +169,7 @@ namespace LibCmo {
|
||||||
dep.ValidGuids.resize(guid_size);
|
dep.ValidGuids.resize(guid_size);
|
||||||
// read data
|
// read data
|
||||||
if (guid_size != 0) {
|
if (guid_size != 0) {
|
||||||
parser->Read(dep.m_Guids.data(), sizeof(CKGUID)* guid_size);
|
parser->Read(dep.m_Guids.data(), sizeof(CKGUID) * guid_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// extra load flag
|
// extra load flag
|
||||||
|
@ -277,7 +277,140 @@ namespace LibCmo {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== manager read ==========
|
// ========== 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return CKERROR::CKERR_OK;
|
return CKERROR::CKERR_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
#include "VTUtils.hpp"
|
||||||
|
#if defined(LIBCMO_OS_WIN32)
|
||||||
|
#define ZLIB_WINAPI
|
||||||
|
#include <zconf.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <zlib.h>;
|
||||||
#include "VTStruct.hpp"
|
#include "VTStruct.hpp"
|
||||||
|
|
||||||
namespace LibCmo {
|
namespace LibCmo {
|
||||||
|
@ -10,12 +17,46 @@ namespace LibCmo {
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
LibCmo::CKStateChunk::CKStateChunk(CK_CLASSID clsid) :
|
||||||
|
m_ClassId(clsid), m_DataDwSize(0u), m_pData(nullptr),
|
||||||
|
m_DataVersion(CK_STATECHUNK_DATAVERSION::CHUNKDATA_CURRENTVERSION), m_ChunkVersion(CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4),
|
||||||
|
m_Parser{ 0u, 0u, 0u },
|
||||||
|
m_ObjectList(), m_ChunkList(), m_ManagerList()
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
CKStateChunk::~CKStateChunk() {
|
CKStateChunk::~CKStateChunk() {
|
||||||
if (this->m_pData != nullptr)
|
if (this->m_pData != nullptr)
|
||||||
delete[] this->m_pData;
|
delete[] this->m_pData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CKStateChunk::ConvertFromOldBuffer(const void* buf, CKDWORD buf_size, CKDWORD blk_size, CK_FILE_WRITEMODE mode) {
|
||||||
|
// if not use compress or 2 size is equal, it mean that this buffer is raw.
|
||||||
|
// assign it directly
|
||||||
|
if (!EnumHelper::FlagEnumHas(mode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
|
||||||
|
buf_size == blk_size) {
|
||||||
|
|
||||||
|
this->m_DataDwSize = buf_size / sizeof(CKDWORD);
|
||||||
|
this->m_pData = new(std::nothrow) CKDWORD[this->m_DataDwSize];
|
||||||
|
if (this->m_pData != nullptr) {
|
||||||
|
memcpy(this->m_pData, buf, this->m_DataDwSize * sizeof(CKDWORD));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// otherwise, we need UnPack
|
||||||
|
// prepare UnPack requirement
|
||||||
|
this->m_DataDwSize = buf_size; // NOTE: store as BYTE length!!!
|
||||||
|
this->m_pData = reinterpret_cast<CKDWORD*>(new(std::nothrow) char[buf_size]);
|
||||||
|
if (this->m_pData == nullptr) return false;
|
||||||
|
memcpy(this->m_pData, buf, buf_size);
|
||||||
|
|
||||||
|
// call UnPack
|
||||||
|
return UnPack(blk_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CKStateChunk::ConvertFromBuffer(const void* buf) {
|
bool CKStateChunk::ConvertFromBuffer(const void* buf) {
|
||||||
if (buf == nullptr) return false;
|
if (buf == nullptr) return false;
|
||||||
|
|
||||||
|
@ -101,7 +142,7 @@ namespace LibCmo {
|
||||||
CK_STATECHUNK_CHUNKOPTIONS options = static_cast<CK_STATECHUNK_CHUNKOPTIONS>(
|
CK_STATECHUNK_CHUNKOPTIONS options = static_cast<CK_STATECHUNK_CHUNKOPTIONS>(
|
||||||
reinterpret_cast<const char*>(buf)[3]
|
reinterpret_cast<const char*>(buf)[3]
|
||||||
);
|
);
|
||||||
|
|
||||||
// read normal data
|
// read normal data
|
||||||
this->m_DataDwSize = dwbuf[1];
|
this->m_DataDwSize = dwbuf[1];
|
||||||
bufpos = 2;
|
bufpos = 2;
|
||||||
|
@ -149,6 +190,39 @@ namespace LibCmo {
|
||||||
return 0u;
|
return 0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CKStateChunk::SeekIdentifier(CKDWORD identifier) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CKStateChunk::UnPack(CKDWORD DestSize) {
|
||||||
|
// NOTE: in UnPack. pData store the compressed buffer, and
|
||||||
|
// dwSize store the length of compressed buffer as CHAR size, not DWORD size!
|
||||||
|
|
||||||
|
// create a enough buffer
|
||||||
|
char* buffer = new(std::nothrow) char[DestSize];
|
||||||
|
if (buffer == nullptr) return false;
|
||||||
|
uLongf destSize = DestSize;
|
||||||
|
// uncompress it
|
||||||
|
auto err = uncompress(
|
||||||
|
reinterpret_cast<Bytef*>(buffer), &destSize,
|
||||||
|
reinterpret_cast<const Bytef*>(this->m_pData), static_cast<uLong>(this->m_DataDwSize)
|
||||||
|
);
|
||||||
|
// if no error, assign data
|
||||||
|
if (err == Z_OK) {
|
||||||
|
// get dw size and copy it to remove useless blank data
|
||||||
|
this->m_DataDwSize = static_cast<CKDWORD>(destSize) / sizeof(CKDWORD);
|
||||||
|
|
||||||
|
delete[] this->m_pData;
|
||||||
|
this->m_pData = nullptr;
|
||||||
|
this->m_pData = new(std::nothrow) CKDWORD[this->m_DataDwSize];
|
||||||
|
if (this->m_pData != nullptr) {
|
||||||
|
memcpy(this->m_pData, buffer, this->m_DataDwSize * sizeof(CKDWORD));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] buffer;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void LibCmo::CKStateChunk::_EnsureEnoughSpace(CKDWORD size) {
|
void LibCmo::CKStateChunk::_EnsureEnoughSpace(CKDWORD size) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "VTUtils.hpp"
|
#include "VTUtils.hpp"
|
||||||
#if defined(LIBCMO_OS_WIN32)
|
#if defined(LIBCMO_OS_WIN32)
|
||||||
#define ZLIB_WINAPI
|
#define ZLIB_WINAPI
|
||||||
#include "zconf.h"
|
#include <zconf.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "VTStruct.hpp"
|
#include "VTStruct.hpp"
|
||||||
|
|
|
@ -85,13 +85,22 @@ namespace LibCmo {
|
||||||
class CKStateChunk {
|
class CKStateChunk {
|
||||||
public:
|
public:
|
||||||
CKStateChunk();
|
CKStateChunk();
|
||||||
|
CKStateChunk(CK_CLASSID clsid);
|
||||||
CKStateChunk(const CKStateChunk&) = delete;
|
CKStateChunk(const CKStateChunk&) = delete;
|
||||||
CKStateChunk& operator=(const CKStateChunk&) = delete;
|
CKStateChunk& operator=(const CKStateChunk&) = delete;
|
||||||
~CKStateChunk();
|
~CKStateChunk();
|
||||||
|
|
||||||
|
bool ConvertFromOldBuffer(const void* buf, CKDWORD buf_size, CKDWORD blk_size, CK_FILE_WRITEMODE mode);
|
||||||
bool ConvertFromBuffer(const void* buf);
|
bool ConvertFromBuffer(const void* buf);
|
||||||
CKDWORD ConvertToBuffer(void* buf);
|
CKDWORD ConvertToBuffer(void* buf);
|
||||||
|
|
||||||
|
bool UnPack(CKDWORD DestSize);
|
||||||
|
CKDWORD GetDataSize(void);
|
||||||
|
|
||||||
|
bool SeekIdentifier(CKDWORD identifier);
|
||||||
|
|
||||||
|
void ReadString(std::string& strl);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CK_CLASSID m_ClassId;
|
CK_CLASSID m_ClassId;
|
||||||
CKDWORD m_DataDwSize;
|
CKDWORD m_DataDwSize;
|
||||||
|
@ -138,7 +147,7 @@ namespace LibCmo {
|
||||||
CK_CLASSID ObjectCid;
|
CK_CLASSID ObjectCid;
|
||||||
void* ObjPtr;
|
void* ObjPtr;
|
||||||
std::string Name;
|
std::string Name;
|
||||||
void* Data;
|
CKStateChunk* Data;
|
||||||
CKDWORD PostPackSize;
|
CKDWORD PostPackSize;
|
||||||
CKDWORD PrePackSize;
|
CKDWORD PrePackSize;
|
||||||
CK_FO_OPTIONS Options;
|
CK_FO_OPTIONS Options;
|
||||||
|
@ -146,6 +155,11 @@ namespace LibCmo {
|
||||||
CK_FILE_WRITEMODE SaveFlags;
|
CK_FILE_WRITEMODE SaveFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CKFileManagerData {
|
||||||
|
CKStateChunk* Data;
|
||||||
|
CKGUID Manager;
|
||||||
|
};
|
||||||
|
|
||||||
struct CKFilePluginDependencies {
|
struct CKFilePluginDependencies {
|
||||||
CK_PLUGIN_TYPE m_PluginCategory;
|
CK_PLUGIN_TYPE m_PluginCategory;
|
||||||
XArray<CKGUID> m_Guids;
|
XArray<CKGUID> m_Guids;
|
||||||
|
@ -170,7 +184,7 @@ namespace LibCmo {
|
||||||
|
|
||||||
int32_t m_SaveIDMax;
|
int32_t m_SaveIDMax;
|
||||||
XArray<CKFileObject> m_FileObject;
|
XArray<CKFileObject> m_FileObject;
|
||||||
//XArray<CKFileManagerData> m_ManagersData;
|
XArray<CKFileManagerData> m_ManagersData;
|
||||||
XClassArray<CKFilePluginDependencies> m_PluginDep;
|
XClassArray<CKFilePluginDependencies> m_PluginDep;
|
||||||
XClassArray<XIntArray> m_IndexByClassId;
|
XClassArray<XIntArray> m_IndexByClassId;
|
||||||
XClassArray<XString> m_IncludedFiles;
|
XClassArray<XString> m_IncludedFiles;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user