write some shit for CKStateChunk
This commit is contained in:
parent
17333527ee
commit
50784e719c
|
@ -228,31 +228,35 @@ namespace LibCmo::CK2 {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A small hint for ToBeNotify, CommonToBeNotify and ToNotify
|
A small hint for ToBeNotify, CommonToBeNotify and ToNotify
|
||||||
Assume that A need notification from B, we can see it as A want buy something from B.
|
Assume that A need notification from B, we can see it as that A want buy something from B.
|
||||||
This relation is represented in ToBeNotify, a pure relation without any inhertance hierarchy.
|
This relation is represented in ToBeNotify, a pure relation without any inhertance hierarchy.
|
||||||
|
|
||||||
Ok, now we assume A have children AA, B also have children BB.
|
Ok, now we assume A have children AA, B also have children BB.
|
||||||
It's okey to order AA to buy something from B, becase AA is the children of A.
|
Because B is a businessman, so his children BB also is a bussinessman.
|
||||||
This relation is represneted in CommonToBeNotify.
|
B and BB have the same goods so A can buy his stuff from both of B and BB.
|
||||||
|
This is the first step executed by ComputeParentsNotifyTable().
|
||||||
|
In this step, the function expand existing business relations to all possible business relations (expand to businessman's children)
|
||||||
|
|
||||||
|
Image there is a candy store, C. Because AA still is a kids.
|
||||||
|
So AA want to buy something from C. Now C is in his ToBeNotify.
|
||||||
|
Additionally, A, the parent of AA, force AA to buy something from B, just for A himself.
|
||||||
For AA, he does not need want to buy something from B, but his parent A order he to do.
|
For AA, he does not need want to buy something from B, but his parent A order he to do.
|
||||||
So AA's ToBeNotify do not have B, but his CommonToBeNotify have B.
|
This is the second step executed by ComputeParentsNotifyTable().
|
||||||
|
For AA, his parent's relations also need to be merged after he processed his relations with C like I introduced previously.
|
||||||
|
|
||||||
|
Now, AA have a full business list writing all trades he can do.
|
||||||
|
This is represented as CommonToBeNotify.
|
||||||
|
In this time, AA's ToBeNotify only have C, but his CommonToBeNotify have B, BB and C.
|
||||||
|
|
||||||
So now, let we change the view from A to B.
|
So now, let we change the view from A to B.
|
||||||
B now can sell something to A or AA. This represent in B's ToNotify.
|
B want to know whom I can sell something to.
|
||||||
|
Because a full trades list are created from A side.
|
||||||
Because B is a bussiness man, as the children of B, let we assume BB also have capability to sell something.
|
The better solution is just ask the guest: do you want to buy something from me?
|
||||||
He initially do not have any bussiness relation, because no one need to buy something from him.
|
This operation will fill ToNotify and is implemented at ComputeHierarchyTable().
|
||||||
But he is smart, he want to use his parent bussiness relation. He copied his parent relation, B's ToNotify.
|
|
||||||
Now BB can trade with A and AA, this represent in his ToNotify.
|
|
||||||
|
|
||||||
Now A and AA know that BB is children of B and B is their bussiness friend.
|
|
||||||
So they also can buy something from BB. This result in that BB is added into their CommonToBeNotify.
|
|
||||||
|
|
||||||
At the end of this story,
|
At the end of this story,
|
||||||
All bussiness man can use ToNofity to see whom they want to sell something to.
|
All bussiness man can use ToNofity to see whom they want to sell something to.
|
||||||
ToNofity list have A and all of his children.
|
|
||||||
And all buyer can use CommonToBeNofity to check who they can buy something from.
|
And all buyer can use CommonToBeNofity to check who they can buy something from.
|
||||||
CommonToBeNotify have B and all of this children.
|
|
||||||
ToBeNotify is just a list to indicate the initial bussiness relation and will never used anymore after real relation established.
|
ToBeNotify is just a list to indicate the initial bussiness relation and will never used anymore after real relation established.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -308,33 +312,6 @@ namespace LibCmo::CK2 {
|
||||||
// set done
|
// set done
|
||||||
desc.Done = true;
|
desc.Done = true;
|
||||||
}
|
}
|
||||||
//static void ComputeParentsNotifyTable(CKClassDesc& desc) {
|
|
||||||
// // if it has done, do not process it again.
|
|
||||||
// if (desc.Done) return;
|
|
||||||
//
|
|
||||||
// // find direct parent
|
|
||||||
// CKClassDesc& parent = g_CKClassInfo[static_cast<size_t>(desc.Parent)];
|
|
||||||
// if (!parent.IsValid) LIBPANIC("No such CK_CLASSID.");
|
|
||||||
|
|
||||||
// // if it is not self inheritance, call recursively
|
|
||||||
// if (desc.Self != desc.Parent) {
|
|
||||||
// ComputeParentsNotifyTable(parent);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // copy parent ToNotify list
|
|
||||||
// desc.ToNotify = parent.ToNotify;
|
|
||||||
// // iterate all desc to know which id need beNotify me
|
|
||||||
// // and add them
|
|
||||||
// for (const auto& checking : g_CKClassInfo) {
|
|
||||||
// if (!checking.IsValid) continue;
|
|
||||||
// if (XContainer::NSXBitArray::IsSet(checking.CommonToBeNotify, static_cast<CKDWORD>(desc.Self))) {
|
|
||||||
// XContainer::NSXBitArray::Set(desc.ToNotify, static_cast<CKDWORD>(checking.Self));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // set done
|
|
||||||
// desc.Done = true;
|
|
||||||
//}
|
|
||||||
static void CKBuildClassHierarchyTable() {
|
static void CKBuildClassHierarchyTable() {
|
||||||
size_t classCount = g_CKClassInfo.size();
|
size_t classCount = g_CKClassInfo.size();
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,6 @@ namespace LibCmo::CK2 {
|
||||||
|
|
||||||
#pragma region Ctor Dtor
|
#pragma region Ctor Dtor
|
||||||
|
|
||||||
//CKStateChunk::CKStateChunk() :
|
|
||||||
// m_ClassId(CK_CLASSID::CKCID_OBJECT), m_DataDwSize(0u), m_pData(nullptr),
|
|
||||||
// m_DataVersion(CK_STATECHUNK_DATAVERSION::CHUNKDATA_CURRENTVERSION), m_ChunkVersion(CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4),
|
|
||||||
// m_Parser{ CKStateChunkStatus::IDLE, 0u, 0u, 0u },
|
|
||||||
// m_ObjectList(), m_ChunkList(), m_ManagerList(),
|
|
||||||
// m_BindDoc(nullptr), m_BindContext(nullptr)
|
|
||||||
//{
|
|
||||||
// ;
|
|
||||||
//}
|
|
||||||
CKStateChunk::CKStateChunk(CKFileVisitor* visitor, CKContext* ctx) :
|
CKStateChunk::CKStateChunk(CKFileVisitor* visitor, CKContext* ctx) :
|
||||||
m_ClassId(CK_CLASSID::CKCID_OBJECT), m_DataDwSize(0u), m_pData(nullptr),
|
m_ClassId(CK_CLASSID::CKCID_OBJECT), m_DataDwSize(0u), m_pData(nullptr),
|
||||||
m_DataVersion(CK_STATECHUNK_DATAVERSION::CHUNKDATA_CURRENTVERSION), m_ChunkVersion(CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4),
|
m_DataVersion(CK_STATECHUNK_DATAVERSION::CHUNKDATA_CURRENTVERSION), m_ChunkVersion(CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4),
|
||||||
|
@ -110,8 +101,10 @@ namespace LibCmo::CK2 {
|
||||||
|
|
||||||
#pragma region Misc Funcs
|
#pragma region Misc Funcs
|
||||||
|
|
||||||
const ChunkProfile CKStateChunk::GetStateChunkProfile() {
|
// ========== Public Funcs ==========
|
||||||
return ChunkProfile {
|
|
||||||
|
const CKStateChunk::ProfileStateChunk_t CKStateChunk::GetStateChunkProfile() {
|
||||||
|
return CKStateChunk::ProfileStateChunk_t {
|
||||||
.m_ClassId = this->m_ClassId,
|
.m_ClassId = this->m_ClassId,
|
||||||
.m_DataDwSize = this->m_DataDwSize,
|
.m_DataDwSize = this->m_DataDwSize,
|
||||||
.m_pData = this->m_pData,
|
.m_pData = this->m_pData,
|
||||||
|
@ -128,7 +121,40 @@ namespace LibCmo::CK2 {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CKStateChunk::Clear(void) {
|
const XContainer::XArray<CKStateChunk::ProfileIdentifier_t> CKStateChunk::GetIdentifiersProfile() {
|
||||||
|
XContainer::XArray<CKStateChunk::ProfileIdentifier_t> collection;
|
||||||
|
if (this->m_Parser.m_Status != CKStateChunkStatus::READ) return collection;
|
||||||
|
|
||||||
|
CKDWORD pos = 0u;
|
||||||
|
if (this->m_DataDwSize < 2u) return collection; // impossible to have a identifier
|
||||||
|
|
||||||
|
// iterate identifier
|
||||||
|
while (true) {
|
||||||
|
// add current identifier
|
||||||
|
CKDWORD nextptr = this->m_pData[pos + 1];
|
||||||
|
if (nextptr == 0u) {
|
||||||
|
nextptr = this->m_DataDwSize; // got tail. no more identifier
|
||||||
|
}
|
||||||
|
collection.emplace_back(CKStateChunk::ProfileIdentifier_t{
|
||||||
|
this->m_pData[pos],
|
||||||
|
this->m_pData + pos + 2,
|
||||||
|
CKSizeof(CKDWORD) * (nextptr - pos - 2u)
|
||||||
|
});
|
||||||
|
|
||||||
|
// move to next identifier or exit
|
||||||
|
// got tail. no more identifier
|
||||||
|
if (this->m_pData[pos + 1] == 0u) break;
|
||||||
|
|
||||||
|
pos = this->m_pData[pos + 1];
|
||||||
|
|
||||||
|
// out of buffer
|
||||||
|
if (pos + 1 >= this->m_DataDwSize) break;
|
||||||
|
};
|
||||||
|
return collection;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKStateChunk::Clear() {
|
||||||
this->m_ClassId = CK_CLASSID::CKCID_OBJECT;
|
this->m_ClassId = CK_CLASSID::CKCID_OBJECT;
|
||||||
this->m_DataVersion = CK_STATECHUNK_DATAVERSION::CHUNK_DEV_2_1;
|
this->m_DataVersion = CK_STATECHUNK_DATAVERSION::CHUNK_DEV_2_1;
|
||||||
this->m_ChunkVersion = CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4;
|
this->m_ChunkVersion = CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4;
|
||||||
|
@ -149,11 +175,11 @@ namespace LibCmo::CK2 {
|
||||||
this->m_ChunkList.clear();
|
this->m_ChunkList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
CKDWORD CKStateChunk::GetDataSize(void) {
|
CKDWORD CKStateChunk::GetDataSize() const {
|
||||||
return CKSizeof(CKDWORD) * this->m_DataDwSize;
|
return CKSizeof(CKDWORD) * this->m_DataDwSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_STATECHUNK_DATAVERSION CKStateChunk::GetDataVersion() {
|
CK_STATECHUNK_DATAVERSION CKStateChunk::GetDataVersion() const {
|
||||||
return this->m_DataVersion;
|
return this->m_DataVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +187,14 @@ namespace LibCmo::CK2 {
|
||||||
this->m_DataVersion = version;
|
this->m_DataVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CK_CLASSID CKStateChunk::GetClassId() const {
|
||||||
|
return this->m_ClassId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CKStateChunk::SetClassId(CK_CLASSID cid) {
|
||||||
|
this->m_ClassId = cid;
|
||||||
|
}
|
||||||
|
|
||||||
bool CKStateChunk::Skip(CKDWORD DwordCount) {
|
bool CKStateChunk::Skip(CKDWORD DwordCount) {
|
||||||
bool result;
|
bool result;
|
||||||
switch (this->m_Parser.m_Status) {
|
switch (this->m_Parser.m_Status) {
|
||||||
|
@ -183,18 +217,7 @@ namespace LibCmo::CK2 {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== Private Funcs ==========
|
||||||
|
|
||||||
void* CKStateChunk::GetCurrentPointer() {
|
|
||||||
switch (this->m_Parser.m_Status) {
|
|
||||||
case CKStateChunkStatus::READ:
|
|
||||||
case CKStateChunkStatus::WRITE:
|
|
||||||
return this->m_pData + this->m_Parser.m_CurrentPos;
|
|
||||||
case CKStateChunkStatus::IDLE:
|
|
||||||
default:
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CKDWORD CKStateChunk::GetCeilDwordSize(size_t char_size) {
|
CKDWORD CKStateChunk::GetCeilDwordSize(size_t char_size) {
|
||||||
return static_cast<CKDWORD>((char_size + 3) >> 2);
|
return static_cast<CKDWORD>((char_size + 3) >> 2);
|
||||||
|
@ -448,33 +471,6 @@ namespace LibCmo::CK2 {
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
//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
|
|
||||||
// CKBYTE* buffer = new CKBYTE[DestSize];
|
|
||||||
// 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) / CKSizeof(CKDWORD);
|
|
||||||
|
|
||||||
// delete[] this->m_pData;
|
|
||||||
// this->m_pData = nullptr;
|
|
||||||
// this->m_pData = new CKDWORD[this->m_DataDwSize];
|
|
||||||
// std::memcpy(this->m_pData, buffer, this->m_DataDwSize * sizeof(CKDWORD));
|
|
||||||
// }
|
|
||||||
// delete[] buffer;
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
#pragma region Read Functions
|
#pragma region Read Functions
|
||||||
|
|
||||||
void CKStateChunk::StartRead(void) {
|
void CKStateChunk::StartRead(void) {
|
||||||
|
@ -529,38 +525,6 @@ namespace LibCmo::CK2 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const XContainer::XArray<IdentifierProfile> CKStateChunk::GetIdentifierProfile() {
|
|
||||||
XContainer::XArray<IdentifierProfile> collection;
|
|
||||||
if (this->m_Parser.m_Status != CKStateChunkStatus::READ) return collection;
|
|
||||||
|
|
||||||
CKDWORD pos = 0u;
|
|
||||||
if (this->m_DataDwSize < 2u) return collection; // impossible to have a identifier
|
|
||||||
|
|
||||||
// iterate identifier
|
|
||||||
while (true) {
|
|
||||||
// add current identifier
|
|
||||||
CKDWORD nextptr = this->m_pData[pos + 1];
|
|
||||||
if (nextptr == 0u) {
|
|
||||||
nextptr = this->m_DataDwSize; // got tail. no more identifier
|
|
||||||
}
|
|
||||||
collection.emplace_back(IdentifierProfile{
|
|
||||||
this->m_pData[pos],
|
|
||||||
this->m_pData + pos + 2,
|
|
||||||
CKSizeof(CKDWORD) * (nextptr - pos - 2u)
|
|
||||||
});
|
|
||||||
|
|
||||||
// move to next identifier or exit
|
|
||||||
// got tail. no more identifier
|
|
||||||
if (this->m_pData[pos + 1] == 0u) break;
|
|
||||||
|
|
||||||
pos = this->m_pData[pos + 1];
|
|
||||||
|
|
||||||
// out of buffer
|
|
||||||
if (pos + 1 >= this->m_DataDwSize) break;
|
|
||||||
};
|
|
||||||
return collection;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========== Basic Data Read Functions ==========*/
|
/* ========== Basic Data Read Functions ==========*/
|
||||||
|
|
||||||
|
|
|
@ -6,25 +6,6 @@
|
||||||
|
|
||||||
namespace LibCmo::CK2 {
|
namespace LibCmo::CK2 {
|
||||||
|
|
||||||
struct ChunkProfile {
|
|
||||||
CK_CLASSID m_ClassId;
|
|
||||||
CKDWORD m_DataDwSize;
|
|
||||||
CKDWORD* m_pData;
|
|
||||||
|
|
||||||
CK_STATECHUNK_DATAVERSION m_DataVersion;
|
|
||||||
CK_STATECHUNK_CHUNKVERSION m_ChunkVersion;
|
|
||||||
|
|
||||||
size_t m_ObjectListSize, m_ChunkListSize, m_ManagerListSize;
|
|
||||||
|
|
||||||
CKFileVisitor* m_BindFile;
|
|
||||||
CKContext* m_BindContext;
|
|
||||||
};
|
|
||||||
struct IdentifierProfile {
|
|
||||||
CKDWORD m_Identifier;
|
|
||||||
void* m_DataPtr;
|
|
||||||
CKDWORD m_AreaSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CKStateChunk {
|
class CKStateChunk {
|
||||||
public:
|
public:
|
||||||
//CKStateChunk();
|
//CKStateChunk();
|
||||||
|
@ -35,6 +16,91 @@ namespace LibCmo::CK2 {
|
||||||
CKStateChunk& operator=(CKStateChunk&&);
|
CKStateChunk& operator=(CKStateChunk&&);
|
||||||
~CKStateChunk();
|
~CKStateChunk();
|
||||||
|
|
||||||
|
#pragma region Self Used Data Struct
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct ProfileStateChunk_t {
|
||||||
|
CK_CLASSID m_ClassId;
|
||||||
|
CKDWORD m_DataDwSize;
|
||||||
|
CKDWORD* m_pData;
|
||||||
|
|
||||||
|
CK_STATECHUNK_DATAVERSION m_DataVersion;
|
||||||
|
CK_STATECHUNK_CHUNKVERSION m_ChunkVersion;
|
||||||
|
|
||||||
|
size_t m_ObjectListSize, m_ChunkListSize, m_ManagerListSize;
|
||||||
|
|
||||||
|
CKFileVisitor* m_BindFile;
|
||||||
|
CKContext* m_BindContext;
|
||||||
|
};
|
||||||
|
struct ProfileIdentifier_t {
|
||||||
|
CKDWORD m_Identifier;
|
||||||
|
void* m_DataPtr;
|
||||||
|
CKDWORD m_AreaSize;
|
||||||
|
};
|
||||||
|
template<bool _TCanWrite>
|
||||||
|
class LockedBuffer_t {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief The type of free function called by this class.
|
||||||
|
* It must have 2 argument, first one is buffer need to be free, second is consumed size.
|
||||||
|
*/
|
||||||
|
using FreeFct = std::function<void(const void*,CKDWORD)>;
|
||||||
|
|
||||||
|
LockedBuffer_t() : m_Ptr(nullptr), m_ConsumedByteSize(0), m_FreeFct(nullptr) {}
|
||||||
|
LockedBuffer_t(const void* ptr, CKDWORD expectedByteSize, FreeFct fct) :
|
||||||
|
m_Ptr(const_cast<CKBYTE*>(static_cast<const CKBYTE*>(ptr))), m_ConsumedByteSize(expectedByteSize), m_FreeFct(fct) {}
|
||||||
|
LockedBuffer_t(const LockedBuffer_t&) = delete;
|
||||||
|
LockedBuffer_t& operator=(const LockedBuffer_t&) = delete;
|
||||||
|
LockedBuffer_t(LockedBuffer_t&& rhs) :
|
||||||
|
m_Ptr(rhs.m_Ptr), m_ConsumedByteSize(rhs.m_ConsumedByteSize), m_FreeFct(rhs.m_FreeFct) {
|
||||||
|
rhs.m_Ptr = nullptr;
|
||||||
|
rhs.m_ConsumedByteSize = 0;
|
||||||
|
rhs.m_FreeFct = nullptr;
|
||||||
|
}
|
||||||
|
LockedBuffer_t& operator=(LockedBuffer_t&& rhs) {
|
||||||
|
// reset self
|
||||||
|
Reset();
|
||||||
|
// copy data
|
||||||
|
m_Ptr = rhs.m_Ptr;
|
||||||
|
m_ConsumedByteSize = rhs.m_ConsumedByteSize;
|
||||||
|
m_FreeFct = rhs.m_FreeFct;
|
||||||
|
// remove rhs data.
|
||||||
|
rhs.m_Ptr = nullptr;
|
||||||
|
rhs.m_ConsumedByteSize = 0;
|
||||||
|
rhs.m_FreeFct = nullptr;
|
||||||
|
}
|
||||||
|
~LockedBuffer_t() {
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
const void* GetPtr() const {
|
||||||
|
return m_Ptr;
|
||||||
|
}
|
||||||
|
// References:
|
||||||
|
// https://stackoverflow.com/questions/43051882/how-to-disable-a-class-member-function-for-certain-template-types
|
||||||
|
// https://stackoverflow.com/questions/13964447/why-compile-error-with-enable-if
|
||||||
|
template<bool _UCanWrite = _TCanWrite, std::enable_if_t<sizeof(_UCanWrite) && _TCanWrite, int> = 0>
|
||||||
|
void* GetMutablePtr() {
|
||||||
|
return m_Ptr;
|
||||||
|
}
|
||||||
|
void SetRealConsumedSize(CKDWORD sizeInByte) {
|
||||||
|
m_ConsumedByteSize = sizeInByte;
|
||||||
|
}
|
||||||
|
void Reset() {
|
||||||
|
if (m_Ptr == nullptr) return;
|
||||||
|
if (m_FreeFct == nullptr) return;
|
||||||
|
m_FreeFct(m_Ptr, m_ConsumedByteSize);
|
||||||
|
|
||||||
|
m_Ptr = nullptr;
|
||||||
|
m_ConsumedByteSize = 0;
|
||||||
|
m_FreeFct = nullptr;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
CKBYTE* m_Ptr;
|
||||||
|
CKDWORD m_ConsumedByteSize;
|
||||||
|
FreeFct m_FreeFct;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class CKStateChunkStatus : CKDWORD {
|
enum class CKStateChunkStatus : CKDWORD {
|
||||||
IDLE,
|
IDLE,
|
||||||
|
@ -48,6 +114,10 @@ namespace LibCmo::CK2 {
|
||||||
CKDWORD m_PrevIdentifierPos;
|
CKDWORD m_PrevIdentifierPos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Member Decl
|
||||||
|
|
||||||
CK_CLASSID m_ClassId;
|
CK_CLASSID m_ClassId;
|
||||||
CKDWORD m_DataDwSize;
|
CKDWORD m_DataDwSize;
|
||||||
CKDWORD* m_pData;
|
CKDWORD* m_pData;
|
||||||
|
@ -64,6 +134,8 @@ namespace LibCmo::CK2 {
|
||||||
CKFileVisitor* m_BindFile;
|
CKFileVisitor* m_BindFile;
|
||||||
CKContext* m_BindContext;
|
CKContext* m_BindContext;
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region Buffer Related
|
#pragma region Buffer Related
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -75,25 +147,66 @@ namespace LibCmo::CK2 {
|
||||||
#pragma region Misc Functions
|
#pragma region Misc Functions
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const ChunkProfile GetStateChunkProfile();
|
// ===== 2 Profiles Getter used by Unvirt =====
|
||||||
|
|
||||||
//bool UnPack(CKDWORD DestSize);
|
/**
|
||||||
void Clear(void);
|
* @brief Get basic info of this CKStateChunk.
|
||||||
CKDWORD GetDataSize(void);
|
* @return The struct describing this CKStateChunk.
|
||||||
CK_STATECHUNK_DATAVERSION GetDataVersion();
|
*/
|
||||||
|
const ProfileStateChunk_t GetStateChunkProfile();
|
||||||
|
/**
|
||||||
|
* @brief Get all indentifier infos of this CKStateChunk,
|
||||||
|
* including identifier self, data area size and address.
|
||||||
|
* @return A arrary, each item describe a single identifier's info.
|
||||||
|
* @remark The detail of implement can be seen in SeekIdentifierAndReturnSize()
|
||||||
|
* @see SeekIdentifierAndReturnSize
|
||||||
|
*/
|
||||||
|
const XContainer::XArray<ProfileIdentifier_t> GetIdentifiersProfile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clear this CKStateChunk, restore it to original status for other using.
|
||||||
|
*/
|
||||||
|
void Clear();
|
||||||
|
/**
|
||||||
|
* @brief Get the size of data buffer in this CKStateChunk.
|
||||||
|
* @return The data buffer's size in CKBYTE.
|
||||||
|
*/
|
||||||
|
CKDWORD GetDataSize() const;
|
||||||
|
/**
|
||||||
|
* @brief Get data version in this CKStateChunk.
|
||||||
|
* @remark Data version is frequently used by calling of CKStateChunk to distinguish different data layout due to compatibility reason.
|
||||||
|
* @return The data version.
|
||||||
|
*/
|
||||||
|
CK_STATECHUNK_DATAVERSION GetDataVersion() const;
|
||||||
|
/**
|
||||||
|
* @brief Set data version of this CKStateChunk.
|
||||||
|
* @param version The set data version
|
||||||
|
* @remark Frequently used when saving someing in CKStateChunk.
|
||||||
|
*/
|
||||||
void SetDataVersion(CK_STATECHUNK_DATAVERSION version);
|
void SetDataVersion(CK_STATECHUNK_DATAVERSION version);
|
||||||
|
/**
|
||||||
|
* @brief Get associated CK_CLASSID of this CKStateChunk
|
||||||
|
* @return Associated CK_CLASSID
|
||||||
|
*/
|
||||||
|
CK_CLASSID GetClassId() const;
|
||||||
|
/**
|
||||||
|
* @brief Set associated CK_CLASSID of this CKStateChunk.
|
||||||
|
* @param cid The set CK_CLASSID
|
||||||
|
* @remark Frequently used at the end of CKObject::Save() override.
|
||||||
|
*/
|
||||||
|
void SetClassId(CK_CLASSID cid);
|
||||||
|
|
||||||
|
|
||||||
bool Skip(CKDWORD DwordCount);
|
bool Skip(CKDWORD DwordCount);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CKDWORD GetCeilDwordSize(size_t char_size);
|
CKDWORD GetCeilDwordSize(size_t char_size);
|
||||||
void* GetCurrentPointer();
|
|
||||||
bool ResizeBuffer(CKDWORD new_dwsize);
|
bool ResizeBuffer(CKDWORD new_dwsize);
|
||||||
bool EnsureWriteSpace(CKDWORD dwsize);
|
bool EnsureWriteSpace(CKDWORD dwsize);
|
||||||
bool EnsureReadSpace(CKDWORD dword_required);
|
bool EnsureReadSpace(CKDWORD dword_required);
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
#pragma region Read Function
|
#pragma region Read Function
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -112,11 +225,14 @@ namespace LibCmo::CK2 {
|
||||||
inline bool SeekIdentifierAndReturnSize(TEnum enum_v, CKDWORD* out_size) {
|
inline bool SeekIdentifierAndReturnSize(TEnum enum_v, CKDWORD* out_size) {
|
||||||
return SeekIdentifierDwordAndReturnSize(static_cast<CKDWORD>(enum_v), out_size);
|
return SeekIdentifierDwordAndReturnSize(static_cast<CKDWORD>(enum_v), out_size);
|
||||||
}
|
}
|
||||||
const XContainer::XArray<IdentifierProfile> GetIdentifierProfile();
|
|
||||||
|
|
||||||
/* ========== Basic Data Read Functions ==========*/
|
/* ========== Basic Data Read Functions ==========*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
bool LockReadBuffer(void** ppData, CKDWORD expectedByteSize);
|
||||||
|
bool UnLockReadBuffer(CKDWORD realConsumedByteSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The base read function for all data.
|
* @brief The base read function for all data.
|
||||||
* This function will check all read requirements.
|
* This function will check all read requirements.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user