update shit
This commit is contained in:
parent
427c9ee06f
commit
522660e65a
|
@ -277,7 +277,140 @@ namespace LibCmo {
|
|||
}
|
||||
|
||||
// ========== 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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
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() {
|
||||
if (this->m_pData != nullptr)
|
||||
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) {
|
||||
if (buf == nullptr) return false;
|
||||
|
||||
|
@ -149,6 +190,39 @@ namespace LibCmo {
|
|||
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) {
|
||||
;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "VTUtils.hpp"
|
||||
#if defined(LIBCMO_OS_WIN32)
|
||||
#define ZLIB_WINAPI
|
||||
#include "zconf.h"
|
||||
#include <zconf.h>
|
||||
#endif
|
||||
|
||||
#include "VTStruct.hpp"
|
||||
|
|
|
@ -85,13 +85,22 @@ namespace LibCmo {
|
|||
class CKStateChunk {
|
||||
public:
|
||||
CKStateChunk();
|
||||
CKStateChunk(CK_CLASSID clsid);
|
||||
CKStateChunk(const CKStateChunk&) = delete;
|
||||
CKStateChunk& operator=(const CKStateChunk&) = delete;
|
||||
~CKStateChunk();
|
||||
|
||||
bool ConvertFromOldBuffer(const void* buf, CKDWORD buf_size, CKDWORD blk_size, CK_FILE_WRITEMODE mode);
|
||||
bool ConvertFromBuffer(const void* buf);
|
||||
CKDWORD ConvertToBuffer(void* buf);
|
||||
|
||||
bool UnPack(CKDWORD DestSize);
|
||||
CKDWORD GetDataSize(void);
|
||||
|
||||
bool SeekIdentifier(CKDWORD identifier);
|
||||
|
||||
void ReadString(std::string& strl);
|
||||
|
||||
private:
|
||||
CK_CLASSID m_ClassId;
|
||||
CKDWORD m_DataDwSize;
|
||||
|
@ -138,7 +147,7 @@ namespace LibCmo {
|
|||
CK_CLASSID ObjectCid;
|
||||
void* ObjPtr;
|
||||
std::string Name;
|
||||
void* Data;
|
||||
CKStateChunk* Data;
|
||||
CKDWORD PostPackSize;
|
||||
CKDWORD PrePackSize;
|
||||
CK_FO_OPTIONS Options;
|
||||
|
@ -146,6 +155,11 @@ namespace LibCmo {
|
|||
CK_FILE_WRITEMODE SaveFlags;
|
||||
};
|
||||
|
||||
struct CKFileManagerData {
|
||||
CKStateChunk* Data;
|
||||
CKGUID Manager;
|
||||
};
|
||||
|
||||
struct CKFilePluginDependencies {
|
||||
CK_PLUGIN_TYPE m_PluginCategory;
|
||||
XArray<CKGUID> m_Guids;
|
||||
|
@ -170,7 +184,7 @@ namespace LibCmo {
|
|||
|
||||
int32_t m_SaveIDMax;
|
||||
XArray<CKFileObject> m_FileObject;
|
||||
//XArray<CKFileManagerData> m_ManagersData;
|
||||
XArray<CKFileManagerData> m_ManagersData;
|
||||
XClassArray<CKFilePluginDependencies> m_PluginDep;
|
||||
XClassArray<XIntArray> m_IndexByClassId;
|
||||
XClassArray<XString> m_IncludedFiles;
|
||||
|
|
Loading…
Reference in New Issue
Block a user