#include "CcosPacket.h" #include "Crc64.h" #include #include #include // 辅助函数:复制内存 template void CopyStream(Type* pTarget, const char* pStr, size_t Size) { char* pcTarget = (char*)pTarget; memcpy(pcTarget, pStr, Size); } // 获取键的灵活性和大小信息 bool GetKeyFlexble(unsigned char* pBuff, bool& Flexible, size_t& LengthSize, size_t& ContextSize) { CCOSKEYST stKey; memcpy(&stKey, pBuff, sizeof(CCOSKEYST)); if (stKey.Flexble) { Flexible = true; LengthSize = 1; for (unsigned char i = 0; i < stKey.ValSize; i++) { LengthSize <<= 1; } } else { Flexible = false; ContextSize = 1; for (unsigned char i = 0; i < stKey.ValSize; i++) { ContextSize <<= 1; } } return true; } // 设置键的灵活值 bool SetKeyFlexbleValue(unsigned char* pBuff, size_t LengthSize, size_t ContextSize) { switch (LengthSize) { case 8: *reinterpret_cast(pBuff) = ContextSize; break; case 4: *reinterpret_cast(pBuff) = ContextSize; break; case 2: *reinterpret_cast(pBuff) = ContextSize; break; case 1: *pBuff = ContextSize; break; default: return false; } return true; } // 获取对象上下文 bool GetObjectContext(char* pData, size_t Size, CCOSKEYTYPE& key, bool& Flexible, char*& pContext, size_t& ContextSize) { if (Size <= sizeof(CCOSKEYST) || pData == nullptr) { return false; } CCOSKEYST Key; memcpy(&Key, pData, sizeof(CCOSKEYST)); key = *reinterpret_cast(pData); if (Key.Flexble) { // 灵活长度处理 size_t ObjSize = 1 << Key.ValSize; if (sizeof(CCOSKEYST) + ObjSize > Size) { return false; } switch (ObjSize) { case 8: ContextSize = *reinterpret_cast(pData + sizeof(CCOSKEYST)); break; case 4: ContextSize = *reinterpret_cast(pData + sizeof(CCOSKEYST)); break; case 2: ContextSize = *reinterpret_cast(pData + sizeof(CCOSKEYST)); break; case 1: ContextSize = *reinterpret_cast(pData + sizeof(CCOSKEYST)); break; default: return false; } if (sizeof(CCOSKEYST) + ObjSize + ContextSize > Size) { return false; } pContext = pData + sizeof(CCOSKEYST) + ObjSize; Flexible = true; } else { // 固定长度处理 ContextSize = 1 << Key.ValSize; if (sizeof(CCOSKEYTYPE) + ContextSize > Size) { return false; } pContext = pData + sizeof(CCOSKEYST); Flexible = false; } return true; } // 检查数据的第一层级结构 bool CheckFirstLevelOfTheData(char* pData, size_t Size) { CCOSKEYTYPE ObjectKey; bool Flexible; char* pObject; size_t ObjectSize; while (Size > 0) { if (!GetObjectContext(pData, Size, ObjectKey, Flexible, pObject, ObjectSize)) { return false; } size_t jumpsize = (pObject - pData) + ObjectSize; if (Size < jumpsize) { return false; } pData += jumpsize; Size -= jumpsize; } return true; } // RawPacketObjectExption 实现 RawPacketObjectExption::RawPacketObjectExption(const char* pExp) : std::runtime_error(pExp) {} RawPacketObjectExption::RawPacketObjectExption(const RawPacketObjectExption& tValue) : std::runtime_error(tValue) {} RawPacketObjectExption& RawPacketObjectExption::operator=(const RawPacketObjectExption& tValue) { if (this != &tValue) { std::runtime_error::operator=(tValue); } return *this; } // RawPacketObject 实现 void RawPacketObject::AddPacketSize(size_t addsize) { m_PacketSize += addsize; if (m_pParent) { m_pParent->AddPacketSize(addsize); } } BOOL RawPacketObject::HasKey() { return m_HasKey; } size_t RawPacketObject::sizeOfRaw() { return m_PacketSize; } size_t RawPacketObject::sizeOfObject() { return m_vec ? m_vec->size() : 0; } size_t RawPacketObject::sizeOfBuff() { return m_BuffSize; } void RawPacketObject::Clear() { if (m_vec) { for (auto obj : *m_vec) { delete obj; } m_vec->clear(); } m_pPacketBuff = nullptr; m_BuffSize = 0; m_PacketSize = 0; } void RawPacketObject::delet() { if (m_InternalMalloc && m_pInternalBuff) { delete m_pInternalBuff; m_pInternalBuff = nullptr; } Clear(); if (m_vec) { delete m_vec; m_vec = nullptr; } } RawPacketObject::RawPacketObject(RawPacketObject* pParent) : m_HasKey(false), m_InternalMalloc(true), m_pParent(pParent), m_pValue(nullptr), m_pPacketBuff(nullptr), m_PacketSize(0), m_BuffSize(1024) { m_pInternalBuff = new std::vector(m_BuffSize); m_pPacketBuff = m_pInternalBuff->data(); m_vec = new std::vector(); } RawPacketObject::RawPacketObject(RawPacketObject* pParent, unsigned char* p, size_t packetsize, size_t buffsize) : m_HasKey(false), m_InternalMalloc(false), m_pParent(pParent), m_pInternalBuff(nullptr), m_pPacketBuff(p), m_PacketSize(packetsize), m_BuffSize(buffsize) { m_vec = new std::vector(); ReloadObject(); } RawPacketObject::~RawPacketObject() { delet(); } bool RawPacketObject::ReloadObject() { if (!m_pPacketBuff || m_PacketSize == 0) { m_pValue = nullptr; m_HasKey = false; return false; } CCOSKEYTYPE key; bool Flexible; char* pObject; size_t ObjectSize; if (!GetObjectContext(reinterpret_cast(m_pPacketBuff), m_PacketSize, key, Flexible, pObject, ObjectSize)) { m_pValue = nullptr; m_HasKey = false; return false; } m_pValue = reinterpret_cast(pObject); m_HasKey = true; size_t jumpsize = (pObject - reinterpret_cast(m_pPacketBuff)) + ObjectSize; bool MultipleObjectExist = (m_PacketSize > jumpsize); if (MultipleObjectExist) { m_HasKey = false; unsigned char* pTemp = m_pPacketBuff; size_t tempSize = m_PacketSize; while (tempSize > 0) { GetObjectContext(reinterpret_cast(pTemp), tempSize, key, Flexible, pObject, ObjectSize); jumpsize = (reinterpret_cast(pObject) - pTemp) + ObjectSize; RawPacketObject* sub = new RawPacketObject(this, pTemp, jumpsize, jumpsize); m_vec->push_back(sub); pTemp += jumpsize; tempSize -= jumpsize; } } else { CCOSKEYST stKey; memcpy(&stKey, m_pPacketBuff, sizeof(CCOSKEYST)); if (stKey.ObjFlag) { unsigned char* pTemp = reinterpret_cast(pObject); size_t tempSize = ObjectSize; while (tempSize > 0) { GetObjectContext(reinterpret_cast(pTemp), tempSize, key, Flexible, pObject, ObjectSize); jumpsize = (reinterpret_cast(pObject) - pTemp) + ObjectSize; RawPacketObject* sub = new RawPacketObject(this, pTemp, jumpsize, jumpsize); m_vec->push_back(sub); pTemp += jumpsize; tempSize -= jumpsize; } } } return true; } void RawPacketObject::Reload(RawPacketObject* pParent, unsigned char* p, size_t packetsize, size_t buffsize) { delet(); m_pParent = pParent; m_pPacketBuff = p; m_PacketSize = packetsize; m_BuffSize = buffsize; ReloadObject(); } void RawPacketObject::SetKey(CCOSKEYTYPE key) { if (m_PacketSize + sizeof(key) > m_BuffSize) { if (m_InternalMalloc) { ReloadInternalMalloc(sizeof(key)); } else { throw RawPacketObjectExption("Key size overflow"); } } memcpy(m_pPacketBuff, &key, sizeof(key)); m_HasKey = true; bool Flexible; size_t LengthSize = 0, ContextSize = 0; GetKeyFlexble(m_pPacketBuff, Flexible, LengthSize, ContextSize); size_t offset = sizeof(key); if (Flexible) { if (m_PacketSize + offset + LengthSize > m_BuffSize) { if (m_InternalMalloc) { ReloadInternalMalloc(LengthSize); } else { throw RawPacketObjectExption("Length size overflow"); } } memset(m_pPacketBuff + offset, 0, LengthSize); m_pValue = m_pPacketBuff + offset + LengthSize; } else { if (m_PacketSize + offset + ContextSize > m_BuffSize) { if (m_InternalMalloc) { ReloadInternalMalloc(ContextSize); } else { throw RawPacketObjectExption("Value size overflow"); } } memset(m_pPacketBuff + offset, 0, ContextSize); m_pValue = m_pPacketBuff + offset; } AddPacketSize(m_pValue - m_pPacketBuff); } bool RawPacketObject::add(CCOSKEYTYPE Key, bool tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, char tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, unsigned char tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, short tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, unsigned short tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, int tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, unsigned int tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, long tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, unsigned long tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, long long tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, unsigned long long tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, float tValue) { return add_Template(Key, tValue); } bool RawPacketObject::add(CCOSKEYTYPE Key, double tValue) { return add_Template(Key, tValue); } void RawPacketObject::ReloadInternalMalloc(size_t sizeofadd) { m_BuffSize += sizeofadd; if (m_pInternalBuff) { m_pInternalBuff->resize(m_BuffSize); m_pPacketBuff = m_pInternalBuff->data(); } } template bool RawPacketObject::add_Template(CCOSKEYTYPE Key, T tValue) { unsigned char* pTempBuff; size_t addSize = 0; bool Flexible; size_t LengthSize = 0; size_t ContextSize = 0; if (m_PacketSize + sizeof(Key) + sizeof(tValue) > sizeOfBuff()) { if (m_InternalMalloc) { ReloadInternalMalloc(sizeof(Key) + sizeof(tValue)); } else { throw RawPacketObjectExption("add size overflow "); return false; } } if (m_HasKey) { GetKeyFlexble(m_pPacketBuff, Flexible, LengthSize, ContextSize); if (!Flexible) { throw RawPacketObjectExption("fixed length can not use add function!"); return false; } } pTempBuff = &(m_pPacketBuff[m_PacketSize]); memcpy(pTempBuff, &Key, sizeof(Key)); GetKeyFlexble(pTempBuff, Flexible, LengthSize, ContextSize); if (Flexible) { throw RawPacketObjectExption("Wring key to satatic values "); return false; } else { addSize = sizeof(Key) + ContextSize; pTempBuff += sizeof(Key); memcpy(pTempBuff, &tValue, ContextSize); } if (!SetKeyLengthValue(addSize)) { throw RawPacketObjectExption("update Length zore value error!"); return false; } RawPacketObject* subRPO = new RawPacketObject(this, (unsigned char*)&(m_pPacketBuff[m_PacketSize]), addSize, addSize); (*m_vec).push_back(subRPO); AddPacketSize(addSize); return true; } template bool RawPacketObject::SignedAssignmentProcess(T1 temp) { bool Flexible; size_t LengthSize = 0; size_t ContextSize = 0; GetKeyFlexble(m_pPacketBuff, Flexible, LengthSize, ContextSize); if (Flexible) { throw RawPacketObjectExption("Flexible length can not use = function!"); return false; } else { switch (ContextSize) { case 8: { //64bit long long Local = (long long)temp; unsigned long long LocalLen = (unsigned long long)Local; memcpy(m_pValue, &LocalLen, sizeof(unsigned long long)); break; } case 4: { //32bit int Local = (int)temp; unsigned int LocalLen = (unsigned int)Local; memcpy(m_pValue, &LocalLen, sizeof(unsigned int)); break; } case 2: { //16bit short Local = (short)temp; unsigned short LocalLen = (unsigned short)Local; memcpy(m_pValue, &LocalLen, sizeof(unsigned short)); break; } case 1: { //8bit char Local = (char)temp; unsigned char LocalLen = (unsigned char)Local; memcpy(m_pValue, &LocalLen, sizeof(unsigned char)); break; } default: throw RawPacketObjectExption("ContextSize error!"); break; } AddPacketSize(ContextSize); } return true; } template bool RawPacketObject::UnSignedAssignmentProcess(T2 temp) { bool Flexible; size_t LengthSize = 0; size_t ContextSize = 0; GetKeyFlexble(m_pPacketBuff, Flexible, LengthSize, ContextSize); if (Flexible) { throw RawPacketObjectExption("Flexible length can not use = function!"); return false; } else { switch (ContextSize) { case 8: { //64bit unsigned long long LocalLen = (unsigned long long)temp; memcpy(m_pValue, &LocalLen, sizeof(unsigned long long)); break; } case 4: { //32bit unsigned int LocalLen = (unsigned int)temp; memcpy(m_pValue, &LocalLen, sizeof(unsigned int)); break; } case 2: { //16bit unsigned short LocalLen = (unsigned short)temp; memcpy(m_pValue, &LocalLen, sizeof(unsigned short)); break; } case 1: { //8bit unsigned char LocalLen = (unsigned char)temp; memcpy(m_pValue, &LocalLen, sizeof(unsigned char)); break; } default: throw RawPacketObjectExption("ContextSize error!"); break; } AddPacketSize(ContextSize); return true; } } template bool RawPacketObject::ReadSignedValueByType(T3& value) { if (m_HasKey) { bool Flexible; size_t LengthSize = 0; size_t ContextSize = 0; GetKeyFlexble(m_pPacketBuff, Flexible, LengthSize, ContextSize); if (Flexible) { throw RawPacketObjectExption("Flexible length can not use = function!"); return false; } else { switch (ContextSize) { case 8: { //64bit unsigned long long LocalLen; memcpy(&LocalLen, m_pValue, sizeof(unsigned long long)); long long Local = (long long)LocalLen; value = (T3)Local; break; } case 4: { //32bit unsigned int LocalLen; memcpy(&LocalLen, m_pValue, sizeof(unsigned int)); int Local = (int)LocalLen; value = (T3)Local; break; } case 2: { //16bit unsigned short LocalLen; memcpy(&LocalLen, m_pValue, sizeof(unsigned short)); short Local = (short)LocalLen; value = (T3)Local; break; } case 1: { //8bit unsigned char LocalLen; memcpy(&LocalLen, m_pValue, sizeof(unsigned char)); char Local = (char)LocalLen; value = (T3)Local; break; } default: throw RawPacketObjectExption("ContextSize error!"); break; } return true; } } else { throw RawPacketObjectExption("Do not have key, can not get value"); return false; } } template bool RawPacketObject::ReadUnSignedValueByType(T4& value) { if (m_HasKey) { bool Flexible; size_t LengthSize = 0; size_t ContextSize = 0; GetKeyFlexble(m_pPacketBuff, Flexible, LengthSize, ContextSize); if (Flexible) { throw RawPacketObjectExption("Flexible length can not use = function!"); return false; } else { switch (ContextSize) { case 8: { //64bit unsigned long long LocalLen; memcpy(&LocalLen, m_pValue, sizeof(unsigned long long)); value = (T4)LocalLen; break; } case 4: { //32bit unsigned int LocalLen; memcpy(&LocalLen, m_pValue, sizeof(unsigned int)); value = (T4)LocalLen; break; } case 2: { //16bit unsigned short LocalLen; memcpy(&LocalLen, m_pValue, sizeof(unsigned short)); value = (T4)LocalLen; break; } case 1: { //8bit unsigned char LocalLen; memcpy(&LocalLen, m_pValue, sizeof(unsigned char)); value = (T4)LocalLen; break; } default: throw RawPacketObjectExption("ContextSize error!"); break; } return true; } } else { throw RawPacketObjectExption("Do not have key, can not get value"); return false; } } bool RawPacketObject::update(const char* pValue, size_t size) { bool Flexible; size_t LengthSize = 0; size_t ContextSize = 0; if (m_HasKey) { GetKeyFlexble(m_pPacketBuff, Flexible, LengthSize, ContextSize); if (Flexible) { if (sizeof(CCOSKEYTYPE) + LengthSize + size > sizeOfBuff()) { throw RawPacketObjectExption("update size overflow "); return false; } memcpy(m_pValue, pValue, size); //set the length value SetKeyFlexbleValue(&(m_pPacketBuff[sizeof(CCOSKEYTYPE)]), LengthSize, size); m_PacketSize = sizeof(CCOSKEYTYPE) + LengthSize + size; } else { if (sizeof(CCOSKEYTYPE) + size > sizeOfBuff()) { throw RawPacketObjectExption("update size overflow "); return false; } memcpy(m_pValue, pValue, ContextSize); m_PacketSize = sizeof(CCOSKEYTYPE) + size; } } else { throw RawPacketObjectExption("Do not have key, can not update value"); return false; } return true; } // 为各种类型实例化模板函数 template bool RawPacketObject::add_Template(CCOSKEYTYPE, bool); template bool RawPacketObject::add_Template(CCOSKEYTYPE, char); template bool RawPacketObject::add_Template(CCOSKEYTYPE, unsigned char); template bool RawPacketObject::add_Template(CCOSKEYTYPE, short); template bool RawPacketObject::add_Template(CCOSKEYTYPE, unsigned short); template bool RawPacketObject::add_Template(CCOSKEYTYPE, int); template bool RawPacketObject::add_Template(CCOSKEYTYPE, unsigned int); template bool RawPacketObject::add_Template(CCOSKEYTYPE, long); template bool RawPacketObject::add_Template(CCOSKEYTYPE, unsigned long); template bool RawPacketObject::add_Template(CCOSKEYTYPE, long long); template bool RawPacketObject::add_Template(CCOSKEYTYPE, unsigned long long); template bool RawPacketObject::add_Template(CCOSKEYTYPE, float); template bool RawPacketObject::add_Template(CCOSKEYTYPE, double); bool RawPacketObject::add(CCOSKEYTYPE Key, const char* pValue, size_t size) { unsigned char* pTempBuff; size_t addSize = 0; bool Flexible; size_t LengthSize = 0; size_t ContextSize = 0; if (m_PacketSize + sizeof(Key) + size > sizeOfBuff()) { if (m_InternalMalloc) { ReloadInternalMalloc(sizeof(Key) + size); } else { throw RawPacketObjectExption("add size overflow "); return false; } } if (m_HasKey) { GetKeyFlexble(m_pPacketBuff, Flexible, LengthSize, ContextSize); if (!Flexible) { throw RawPacketObjectExption("fixed length can not use add function!"); return false; } } pTempBuff = &(m_pPacketBuff[m_PacketSize]); memcpy(pTempBuff, &Key, sizeof(Key)); GetKeyFlexble(pTempBuff, Flexible, LengthSize, ContextSize); if (Flexible) { addSize = sizeof(Key) + LengthSize + size; if (m_PacketSize + addSize > sizeOfBuff()) { if (m_InternalMalloc) { ReloadInternalMalloc(LengthSize); } else { throw RawPacketObjectExption("Length size overflow "); return false; } } pTempBuff += sizeof(Key); SetKeyFlexbleValue(pTempBuff, LengthSize, size); pTempBuff += LengthSize; memcpy(pTempBuff, pValue, size); } else { addSize = sizeof(Key) + ContextSize; pTempBuff += sizeof(Key); memcpy(pTempBuff, pValue, ContextSize); } if (!SetKeyLengthValue(addSize)) { throw RawPacketObjectExption("update Length zore value error!"); return false; } RawPacketObject* subRPO = new RawPacketObject(this, (unsigned char*)&(m_pPacketBuff[m_PacketSize]), addSize, addSize); (*m_vec).push_back(subRPO); AddPacketSize(addSize); return true; } bool RawPacketObject::add(RawPacketObject& dataobj) { if (&dataobj == this) { return false; } bool Flexible; size_t LengthSize = 0; size_t ContextSize = 0; if (m_HasKey) { GetKeyFlexble(m_pPacketBuff, Flexible, LengthSize, ContextSize); if (!Flexible) { throw RawPacketObjectExption("fixed length can not use add function!"); return false; } } if (m_PacketSize + dataobj.sizeOfRaw() > sizeOfBuff()) { if (m_InternalMalloc) { ReloadInternalMalloc(dataobj.sizeOfRaw()); } else { throw RawPacketObjectExption("add size overflow "); return false; } } if (m_HasKey) { if (!SetKeyLengthValue(dataobj.sizeOfRaw())) { throw RawPacketObjectExption("update Length zore value error!"); return false; } } memcpy(&(m_pPacketBuff[m_PacketSize]), dataobj.m_pPacketBuff, dataobj.sizeOfRaw()); unsigned char* p = &(m_pPacketBuff[m_PacketSize]); size_t packetsize = dataobj.sizeOfRaw(); size_t buffsize = dataobj.sizeOfRaw(); RawPacketObject* addobj = new RawPacketObject(this, p, packetsize, buffsize); (*m_vec).push_back(addobj); AddPacketSize(packetsize); return true; } bool RawPacketObject::SetKeyLengthValue(size_t addSize) { bool Flexible; size_t LengthSize = 0; size_t ContextSize = 0; unsigned char* pTempBuff; if (m_HasKey)//update Length zore value { GetKeyFlexble(m_pPacketBuff, Flexible, LengthSize, ContextSize); if (Flexible) { size_t LengthZoreValue = 0; pTempBuff = m_pPacketBuff + sizeof(CCOSKEYTYPE); memcpy(&LengthZoreValue, pTempBuff, LengthSize); size_t TempSize = addSize + LengthZoreValue; SetKeyFlexbleValue(pTempBuff, LengthSize, TempSize); } } return true; } // 赋值操作实现 RawPacketObject& RawPacketObject::operator=(const RawPacketObject& tValue) { if (this == &tValue) return *this; size_t newSize = tValue.m_PacketSize; if (m_BuffSize < newSize) { if (m_InternalMalloc) { ReloadInternalMalloc(newSize - m_BuffSize); } else { throw RawPacketObjectExption("new obj's BuffSize too long"); } } memcpy(m_pPacketBuff, tValue.m_pPacketBuff, newSize); Reload(tValue.m_pParent, m_pPacketBuff, newSize, newSize); return *this; } // 各种类型的赋值操作 RawPacketObject& RawPacketObject::operator=(const bool tValue) { return *this = static_cast(tValue); } // 读取操作实现 RawPacketObject& RawPacketObject::operator[](size_t idx) { if (idx >= sizeOfObject()) { throw RawPacketObjectExption("overflow of Idx Of []"); } return *(*m_vec)[idx]; } RawPacketObject& RawPacketObject::operator[](int idx) { if (idx < 0) { throw RawPacketObjectExption("using minus idx to operate []"); } return operator[](static_cast(idx)); } RawPacketObject& RawPacketObject::operator[](CCOSKEYTYPE Key) { for (auto obj : *m_vec) { CCOSKEYTYPE objKey; memcpy(&objKey, obj->m_pPacketBuff, sizeof(CCOSKEYTYPE)); if (objKey == Key) { return *obj; } } throw RawPacketObjectExption("none matches the operator param"); } // 类型转换操作 RawPacketObject::operator bool() { if (IsObject()) throw RawPacketObjectExption("try to convert a object"); return *reinterpret_cast(m_pValue); } bool RawPacketObject::operator==(const RawPacketObject& ar) const { return m_PacketSize == ar.m_PacketSize && memcmp(m_pPacketBuff, ar.m_pPacketBuff, m_PacketSize) == 0; } // CcosPacket 实现 CcosPacket::CcosPacket() : SCFPacket(), m_pDataObj(nullptr), m_bReady(false), m_LenzoneSize(4), m_CrcEffective(false), m_Direction(0), m_FreezeLenzone(1) { } CcosPacket::CcosPacket(char* pData, size_t Length) : SCFPacket(pData, Length), m_pDataObj(nullptr) { UpdateLastEnv(); } CcosPacket::~CcosPacket() { if (m_pDataObj) { delete m_pDataObj; } } bool CcosPacket::UpdateLastEnv() { bool res = true; unsigned int Lenzonesize = 0; if (GetLenZoneSize(Lenzonesize) == false) { res = false; } bool Effective = false; if (res == true && GetDataCrcEffectiveFlag(Effective) == false) { res = false; } unsigned int Direction = 0; if (res == true && GetTargetDirection(Direction) == false) { res = false; } unsigned int FreezeLenzone = 0; if (res == true && GetFreezeLenZoneFlag(FreezeLenzone) == false) { res = false; } if (res) { m_bReady = true; m_CrcEffective = Effective; m_Direction = Direction; m_LenzoneSize = Lenzonesize; m_FreezeLenzone = FreezeLenzone; } else { m_bReady = false; } return res; } // 各种访问方法实现 bool CcosPacket::GetPhyDevIdx(PHYIDXTYPE& PhyDevIdx) { if (!m_bReady) return false; PhyDevIdx = m_PacketBuff[DP_PHYIDX_OFFSET]; return true; } bool CcosPacket::SetPhyDevIdx(PHYIDXTYPE PhyDevIdx) { if (m_bReady) return false; m_PacketBuff[DP_PHYIDX_OFFSET] = PhyDevIdx; return true; } bool CcosPacket::GetLogicDevIdx(LOGICIDXTYPE& LogicDevIdx) { bool ret = false; //if (m_bReady) { LogicDevIdx = m_PacketBuff[DP_LOGICIDX_OFFSET]; ret = true; } return ret; } bool CcosPacket::SetLogicDevIdx(LOGICIDXTYPE LogicDevIdx) { bool ret = false; if (m_bReady == false) { m_PacketBuff[DP_LOGICIDX_OFFSET] = LogicDevIdx; ret = true; } return ret; } bool CcosPacket::GetDataCrcEffectiveFlag(bool& Effective) { bool ret = false; //if (m_bReady) { CCOSPACKETFLAG Dst = { 0 }; CopyStream(&Dst, &m_PacketBuff[DP_FLAG_OFFSET], 1); Effective = Dst.CrcEffective; ret = true; } return ret; } bool CcosPacket::SetDataCrcEffectiveFlag(bool Effective) { bool ret = false; if (m_bReady == false) { CCOSPACKETFLAG Dst = { 0 }; CopyStream(&Dst, &m_PacketBuff[DP_FLAG_OFFSET], 1); Dst.CrcEffective = Effective; CopyStream(&m_PacketBuff[DP_FLAG_OFFSET], (const char*)&Dst, 1); ret = true; } return ret; } bool CcosPacket::GetTargetDirection(unsigned int& Direction) { bool ret = false; //if (m_bReady) { CCOSPACKETFLAG Dst = { 0 }; CopyStream(&Dst, &m_PacketBuff[DP_FLAG_OFFSET], 1); Direction = Dst.PackDirection; ret = true; } return ret; } bool CcosPacket::SetTargetDirection(unsigned int Direction) { bool ret = false; if (Direction > 2) { return ret; } if (m_bReady == false) { CCOSPACKETFLAG Dst = { 0 }; CopyStream(&Dst, &m_PacketBuff[DP_FLAG_OFFSET], 1); Dst.PackDirection = Direction; CopyStream(&m_PacketBuff[DP_FLAG_OFFSET], (const char*)&Dst, 1); ret = true; } return ret; } bool CcosPacket::GetFreezeLenZoneFlag(unsigned int& FreezeFlag) { bool ret = false; //if (m_bReady) { CCOSPACKETFLAG Dst = { 0 }; CopyStream(&Dst, &m_PacketBuff[DP_FLAG_OFFSET], 1); FreezeFlag = Dst.FreezeOfLenZone; ret = true; } return ret; } bool CcosPacket::SetFreezeLenZoneFlag(unsigned int FreezeFlag) { bool ret = false; if (m_bReady == false) { CCOSPACKETFLAG Dst = { 0 }; CopyStream(&Dst, &m_PacketBuff[DP_FLAG_OFFSET], 1); Dst.FreezeOfLenZone = FreezeFlag; CopyStream(&m_PacketBuff[DP_FLAG_OFFSET], (const char*)&Dst, 1); ret = true; } return ret; } bool CcosPacket::GetLenZoneSize(unsigned int& LenzoneSize) { bool ret = false; //if (m_bReady) { CCOSPACKETFLAG Dst = { 0 }; CopyStream(&Dst, &m_PacketBuff[DP_FLAG_OFFSET], 1); // 111b if (Dst.SizeOfLenZon == 7) { LenzoneSize = 0;//no Lenzone } else { LenzoneSize = 1; for (unsigned int i = 0; i < Dst.SizeOfLenZon; i++) { LenzoneSize = LenzoneSize << 1; } } ret = true; } return ret; } bool CcosPacket::SetLenZoneSize(unsigned int LenzoneSize) { bool ret = false; if (LenzoneSize > 64) { return ret; } if (m_bReady == false) { CCOSPACKETFLAG Dst = { 0 }; CopyStream(&Dst, &m_PacketBuff[DP_FLAG_OFFSET], 1); switch (LenzoneSize) { case 0: Dst.SizeOfLenZon = 7; break; case 1: Dst.SizeOfLenZon = 0; break; case 2: Dst.SizeOfLenZon = 1; break; case 4: Dst.SizeOfLenZon = 2; break; case 8: Dst.SizeOfLenZon = 3; break; //case 16: // Dst.SizeOfLenZon = 4; // break; //case 32: // Dst.SizeOfLenZon = 5; // break; //case 64: // Dst.SizeOfLenZon = 6; // break; default: return false; break; } CopyStream(&m_PacketBuff[DP_FLAG_OFFSET], (const char*)&Dst, 1); m_LenzoneSize = LenzoneSize; ret = true; } return ret; } bool CcosPacket::GetCommand(CCOSCMDTYPE& Cmd) { bool ret = false; //if (m_bReady) { Cmd = m_PacketBuff[DP_CMD_OFFSET]; ret = true; } return ret; } bool CcosPacket::SetCommand(CCOSCMDTYPE Cmd) { bool ret = false; if (m_bReady == false) { m_PacketBuff[DP_CMD_OFFSET] = Cmd; ret = true; } return ret; } bool CcosPacket::GetRetcode(char& Ret) { bool ret = false; //if (m_bReady) { Ret = m_PacketBuff[DP_RET_OFFSET]; ret = true; } return ret; } bool CcosPacket::SetRetcode(char Ret) { bool ret = false; if (m_bReady == false) { m_PacketBuff[DP_RET_OFFSET] = Ret; ret = true; } return ret; } bool CcosPacket::GetDataLen(unsigned long long& Len) { bool ret = false; //if (m_bReady) { unsigned int LenzoneSize = 0; if (GetLenZoneSize(LenzoneSize)) { switch (LenzoneSize) { case 8: { //64bit CopyStream(&Len, &m_PacketBuff[DP_PARAMLEN_OFFSET], sizeof(Len)); ret = true; } break; case 4: { //32bit unsigned int LocalLen = 0; CopyStream(&LocalLen, &m_PacketBuff[DP_PARAMLEN_OFFSET], sizeof(LocalLen)); Len = LocalLen; ret = true; } break; case 2: { //16bit unsigned short LocalLen = 0; CopyStream(&LocalLen, &m_PacketBuff[DP_PARAMLEN_OFFSET], sizeof(LocalLen)); Len = LocalLen; ret = true; } break; case 1: { //8bit unsigned char LocalLen = 0; CopyStream(&LocalLen, &m_PacketBuff[DP_PARAMLEN_OFFSET], sizeof(LocalLen)); Len = LocalLen; ret = true; } break; default: //零和大于8字节的一律无视 break; } } } return ret; } bool CcosPacket::SetDataLen(unsigned long long Len) { bool ret = false; if (m_bReady == false) { unsigned int LenzoneSize = 0; if (GetLenZoneSize(LenzoneSize)) { switch (LenzoneSize) { case 8: { //64bit CopyStream(&m_PacketBuff[DP_PARAMLEN_OFFSET], (const char*)&Len, sizeof(Len)); ret = true; } break; case 4: { //32bit unsigned int LocalLen = (unsigned int)Len; CopyStream(&m_PacketBuff[DP_PARAMLEN_OFFSET], (const char*)&LocalLen, sizeof(LocalLen)); ret = true; } break; case 2: { //16bit unsigned short LocalLen = (unsigned short)Len; CopyStream(&m_PacketBuff[DP_PARAMLEN_OFFSET], (const char*)&LocalLen, sizeof(LocalLen)); ret = true; } break; case 1: { //8bit unsigned char LocalLen = (unsigned char)Len; CopyStream(&m_PacketBuff[DP_PARAMLEN_OFFSET], (const char*)&LocalLen, sizeof(LocalLen)); ret = true; } break; default: //零和大于8字节的一律无视 break; } } } return ret; } bool CcosPacket::GetHeadsCrc(unsigned short& headCrc16) { bool ret = false; //if (m_bReady) { unsigned int LenzoneSize = 0; if (GetLenZoneSize(LenzoneSize)) { CopyStream(&headCrc16, &m_PacketBuff[DP_PARAMLEN_OFFSET + LenzoneSize], sizeof(headCrc16)); ret = true; } } return ret; } bool CcosPacket::SetHeadsCrc(unsigned short headCrc16) { bool ret = false; if (m_bReady == false) { unsigned int LenzoneSize = 0; if (GetLenZoneSize(LenzoneSize)) { CopyStream(&m_PacketBuff[DP_PARAMLEN_OFFSET + LenzoneSize], (const char*)&headCrc16, sizeof(headCrc16)); ret = true; } } return ret; } char* CcosPacket::GetData() { size_t headSize = GetHeadSize(); return headSize > 0 ? m_PacketBuff + headSize : nullptr; } size_t CcosPacket::GetHeadSize() { return DP_PARAMLEN_OFFSET + m_LenzoneSize + DP_CRC16_SIZE; } unsigned long long CcosPacket::GetCcosPacketSize() { unsigned long long TotalPacketSize = 0; size_t HeadSize = GetHeadSize(); if (HeadSize > 0) { unsigned int LenzoneSize = 0; GetLenZoneSize(LenzoneSize); if (LenzoneSize == 0) { return HeadSize; } unsigned long long DataLen = 0; if (GetDataLen(DataLen) == false) { return 0; } unsigned long long TotalPacketSize = HeadSize + DataLen; if (DataLen > 0) { TotalPacketSize += DP_CRC16_SIZE; } if (HeadSize == 0 || TotalPacketSize > GetBuffLen()) { return 0; } return TotalPacketSize; } return 0; } bool CcosPacket::GetParam(DWORD Idx, char*& pAddress, size_t& ParamSize) { CCOSKEYTYPE ObjectKey; bool Flexible; char* pObject = NULL; size_t ObjectSize; unsigned long long DataLen = 0; size_t HeadSize = GetHeadSize(); if (GetDataLen(DataLen) == false || DataLen == 0) { return false; } size_t Size = DataLen; char* pData = &m_PacketBuff[HeadSize]; for (DWORD i = 0; i <= Idx; i++) { if (GetObjectContext(pData, Size, ObjectKey, Flexible, pObject, ObjectSize)) { //calculate jump size size_t jumpsize = (pObject - pData) + ObjectSize; if (Size > jumpsize) { pData += jumpsize; Size -= jumpsize; continue; } else if (Size == jumpsize) { //must be Size == jumpsize!!!! //return true; continue; } return false; } else { return false;; } } pAddress = pObject; ParamSize = ObjectSize; return true; } RawPacketObject* CcosPacket::GetDataObject() { if (!m_pDataObj) { unsigned long long dataLen = 0; GetDataLen(dataLen); size_t headSize = GetHeadSize(); size_t buffSize = GetBuffLen() - headSize; m_pDataObj = new RawPacketObject(nullptr, reinterpret_cast(GetData()), dataLen, buffSize); } return m_pDataObj; } bool CcosPacket::SetData(const char* pData, size_t dataLen) { size_t HeadSize = GetHeadSize(); if (HeadSize > 0) { unsigned long long PacketSize = (HeadSize + dataLen + DP_CRC16_SIZE); //check the packet buffer if (GetBuffLen() < PacketSize) { //bufflen not enough if (SetBuffLen(PacketSize) == false) { //mem allocation failed return false; } } //copy data memcpy(&m_PacketBuff[HeadSize], pData, dataLen); //update lenzone PacketSize = (unsigned long long)dataLen; return SetDataLen(PacketSize); } return false; } bool CcosPacket::AddData(const char* pData, size_t dataLen) { size_t HeadSize = GetHeadSize(); if (HeadSize > 0) { //exist lenzone unsigned long long DataSize = 0; if (GetDataLen(DataSize)) { // unsigned long long PacketSize = (HeadSize + DataSize + dataLen + DP_CRC16_SIZE); //check the packet buffer if (GetBuffLen() < PacketSize) { //bufflen not enough if (SetBuffLen(PacketSize) == false) { //mem allocation failed return false; } } //copy data unsigned long long CopyPosition = HeadSize + DataSize; memcpy(&m_PacketBuff[CopyPosition], pData, dataLen); DataSize += dataLen; //update lenzone return SetDataLen(DataSize); } } return false; } bool CcosPacket::GetDataCrc(unsigned short& dataCrc16) { bool ret = false; size_t HeadSize = GetHeadSize(); if (HeadSize > 0) { unsigned long long DataSize = 0; if (GetDataLen(DataSize)) { unsigned long long CrcPosition = HeadSize + DataSize; CopyStream((const char*)&dataCrc16, &m_PacketBuff[CrcPosition], sizeof(dataCrc16)); ret = true; } } return ret; } bool CcosPacket::SetDataCrc(unsigned short dataCrc16) { bool ret = false; size_t HeadSize = GetHeadSize(); if (HeadSize > 0) { unsigned long long DataSize = 0; if (GetDataLen(DataSize)) { unsigned long long CrcPosition = HeadSize + DataSize; CopyStream(&m_PacketBuff[CrcPosition], (const char*)&dataCrc16, sizeof(dataCrc16)); ret = true; } } return ret; } // 初始化包 bool CcosPacket::InitPacket() { m_PacketBuff[DP_HEAD_OFFSET] = DP_HEAD; m_PacketBuff[DP_VER_OFFSET] = 0x01; SetPhyDevIdx(0); SetLogicDevIdx(0); SetDataCrcEffectiveFlag(m_CrcEffective); SetTargetDirection(m_Direction); SetFreezeLenZoneFlag(m_FreezeLenzone); SetLenZoneSize(m_LenzoneSize); SetRetcode(0); SetDataLen(0); return true; } // 准备包 bool CcosPacket::ReadyPacket() { //simple check //head if (m_PacketBuff[DP_HEAD_OFFSET] != (char)DP_HEAD) { return false; } //direction unsigned int Direction = 3; if (GetTargetDirection(Direction) == false || Direction > 2) { return false; } unsigned int LenzonSize = 0; if (GetLenZoneSize(LenzonSize) == false || LenzonSize > 8) { return false; } unsigned long long DataLen = 0; if (GetDataLen(DataLen) == false) { return false; } //check bufflen & packetlen size_t HeadSize = GetHeadSize(); size_t TotalPacketSize = GetCcosPacketSize(); if (HeadSize == 0 || TotalPacketSize == 0) { return false; } //make head's crc unsigned short crc16 = CRC16((unsigned char*)&m_PacketBuff[DP_HEAD_OFFSET], HeadSize - DP_CRC16_SIZE); if (SetHeadsCrc(crc16) == false) { return false; } //check first level of data if (DataLen > 0) { if (CheckFirstLevelOfTheData(&m_PacketBuff[HeadSize], DataLen) == false) { return false; } } //make data's crc if (DataLen > 0) { crc16 = CRC16((unsigned char*)&m_PacketBuff[HeadSize], DataLen); if (SetDataCrc(crc16) == false) { return false; } } if (UpdateLastEnv() == false) { return false; } SetPacketLen(TotalPacketSize); return true; } // C接口函数实现 extern "C" PVOID MallocCcosPacket() { return new CcosPacket(); } extern "C" void ReleaseCcosPacket(PVOID pObj) { delete static_cast(pObj); } extern "C" PACKET_RET CcosPacketParser(const char* pRecData, DWORD nLength, DWORD& PacketLength) { //head DWORD i = 0; for (; i < nLength; i++) { if (pRecData[i] != (char)DP_HEAD) { continue; } else { break; } } if (i > 0) { PacketLength = i; return PACKET_USELESS; } //ver if (nLength < 2) { return PACKET_NOPACKET; } if (pRecData[DP_VER_OFFSET] != (char)0x01) { PacketLength = DP_VER_OFFSET + 1; return PACKET_USELESS; } //read packet to cmd part if (nLength < DP_CMD_OFFSET + 1) { return PACKET_NOPACKET; } //get flag----------------------------- CCOSPACKETFLAG df; CopyStream((const char*)&df, &pRecData[DP_FLAG_OFFSET], sizeof(CCOSPACKETFLAG)); //check direction if (df.PackDirection > 2) { PacketLength = DP_FLAG_OFFSET + 1; return PACKET_USELESS; } //get len zonesize unsigned int LenzoneSize; if (df.SizeOfLenZon == 7) { LenzoneSize = 0;//no Lenzone } else { LenzoneSize = 1; for (unsigned int i = 0; i < df.SizeOfLenZon; i++) { LenzoneSize = LenzoneSize << 1; } } //crc effective bool CrcEffective = df.CrcEffective; //freeze lenzone unsigned int FreezeLenzone = df.FreezeOfLenZone; //cmd-------------------------- unsigned int Cmd = pRecData[DP_CMD_OFFSET]; //get DataLen------------------ //check if (nLength < DP_PARAMLEN_OFFSET + LenzoneSize) { return PACKET_NOPACKET; } unsigned long long DataLen = 0; if (LenzoneSize > 0) { switch (LenzoneSize) { case 8: { //64bit CopyStream(&DataLen, &pRecData[DP_PARAMLEN_OFFSET], sizeof(DataLen)); } break; case 4: { //32bit unsigned int LocalLen = 0; CopyStream(&LocalLen, &pRecData[DP_PARAMLEN_OFFSET], sizeof(LocalLen)); DataLen = LocalLen; } break; case 2: { //16bit unsigned short LocalLen = 0; CopyStream(&LocalLen, &pRecData[DP_PARAMLEN_OFFSET], sizeof(LocalLen)); DataLen = LocalLen; } break; case 1: { //8bit unsigned char LocalLen = 0; CopyStream(&LocalLen, &pRecData[DP_PARAMLEN_OFFSET], sizeof(LocalLen)); DataLen = LocalLen; } default: { //其他都是浮云 PacketLength = (DP_PARAMLEN_OFFSET + LenzoneSize); return PACKET_USELESS; } break; } } //get Crc & check if (nLength < DP_PARAMLEN_OFFSET + LenzoneSize + DP_CRC16_SIZE) { return PACKET_NOPACKET; } //check the Head crc unsigned short HeadCalcCrc = CRC16((unsigned char*)&pRecData[DP_HEAD_OFFSET], DP_PARAMLEN_OFFSET + LenzoneSize); unsigned short HeadPacketCrc = 0; CopyStream(&HeadPacketCrc, &pRecData[DP_PARAMLEN_OFFSET + LenzoneSize], DP_CRC16_SIZE); unsigned long long dataOffset = DP_PARAMLEN_OFFSET + LenzoneSize + DP_CRC16_SIZE; if (HeadCalcCrc != HeadPacketCrc) { PacketLength = dataOffset; return PACKET_USELESS; } //head's crc check is done if (LenzoneSize == 0 || DataLen == 0) { //done here PacketLength = dataOffset; //for test #ifdef _DEBUG //printf("\n\nGot Ccos Packet---------------------Dir:%d\n\n", df.PackDirection); #endif return PACKET_ISPACKET; } //get data & check if (nLength < dataOffset + DataLen) { return PACKET_NOPACKET; } if (CheckFirstLevelOfTheData((char*)&pRecData[dataOffset], DataLen) == false) { PacketLength = dataOffset + DataLen; return PACKET_USELESS; } //get crc if (nLength < dataOffset + DataLen + DP_CRC16_SIZE) { return PACKET_NOPACKET; } if (CrcEffective) { unsigned short DataCalcCrc = CRC16((unsigned char*)&pRecData[dataOffset], DataLen); unsigned short DataPacketCrc; CopyStream(&DataPacketCrc, &pRecData[dataOffset + DataLen], DP_CRC16_SIZE); if (DataCalcCrc != DataPacketCrc) { PacketLength = dataOffset + DataLen + DP_CRC16_SIZE; return PACKET_USELESS; } } PacketLength = dataOffset + DataLen + DP_CRC16_SIZE; //for test #ifdef _DEBUG //printf("\n\nGot Ccos Packet---------------------Dir:%d.packet Len:%d\n\n", df.PackDirection, PacketLength); #endif return PACKET_ISPACKET; }