CppUtils/Utils/DataPack.cpp

348 lines
8.4 KiB
C++
Raw Normal View History

2025-06-05 10:06:43 +08:00
#pragma once
#include "DataPack.h"
#include <string>
#include <vector>
enum class DataPachKey : uint8_t
{
FileStart = 0x81,
FileEnd = 0x98,
IdStart = 0xC7,
IdEnd = 0xC8,
ValueStart = 0x55,
ValueEnd = 0x56,
ValueStart_Small = 0x57,
ValueStart_Small_X = 0x58,
ChildStart = 0xD4,
ChildEnd = 0xD5,
ChildStart_Small = 0xD6,
ChildStart_Small_X = 0xD7,
};
int DataPack::GetCount()
{
return this->Child.size();
}
void DataPack::SetCount(int value)
{
this->Child.resize(value);
}
DataPack& DataPack::operator[](int index)
{
return this->Child[index];
}
DataPack& DataPack::operator[](std::string id)
{
for (int i = 0; i < Child.size(); i++)
{
if (this->Child[i].Id == id)
{
return this->Child[i];
}
}
Child.push_back(DataPack(id, 0));
return this->Child[this->Child.size() - 1];
}
void DataPack::operator=(const std::initializer_list<uint8_t> data)
{
this->Value.resize(data.size());
memcpy(this->Value.data(), data.begin(), data.size());
}
void DataPack::operator=(const std::initializer_list<uint8_t>* data)
{
this->Value.resize(data->size());
memcpy(this->Value.data(), data->begin(), data->size());
}
void DataPack::operator=(const char* data)
{
std::string str = data;
this->Value.resize(str.size());
memcpy(this->Value.data(), str.c_str(), str.size());
}
void DataPack::operator=(const wchar_t* data)
{
std::wstring str = data;
this->Value.resize(str.size() * 2);
memcpy(this->Value.data(), str.c_str(), str.size() * 2);
}
void DataPack::operator=(char* data)
{
std::string str = data;
this->Value.resize(str.size());
memcpy(this->Value.data(), str.c_str(), str.size());
}
void DataPack::operator=(wchar_t* data)
{
std::wstring str = data;
this->Value.resize(str.size() * 2);
memcpy(this->Value.data(), str.c_str(), str.size() * 2);
}
void DataPack::operator=(std::string data)
{
this->Value.resize(data.size());
memcpy(this->Value.data(), data.c_str(), data.size());
}
void DataPack::operator=(std::wstring data)
{
this->Value.resize(data.size() * 2);
memcpy(this->Value.data(), data.c_str(), data.size() * 2);
}
void DataPack::RemoveAt(int index)
{
this->Child.erase(this->Child.begin() + index);
}
DataPack::DataPack() :Id(""), Value(std::vector<uint8_t>()) {}
DataPack::DataPack(const uint8_t* data, int data_len)
{
int index = 0;
int bufferSize = 0;
if (data_len < 4)
return;
if (data[0] == (uint8_t)DataPachKey::FileStart)
{
bufferSize = *(int*)&data[1];
index = 5;
}
else
{
return;
}
if (data[bufferSize - 1] != (uint8_t)DataPachKey::FileEnd)
{
return;
}
while (index < bufferSize - 1)
{
DataPachKey key = (DataPachKey)data[index];
switch (key)
{
case DataPachKey::IdStart:
{
index += 1;
uint16_t idLen = *(uint16_t*)&data[index];
index += 2;
if (data[index + idLen] != (uint8_t)DataPachKey::IdEnd)
return;
this->Id.assign((char*)&data[index], idLen);
index += idLen + 1;
break;
}
case DataPachKey::ValueStart:
{
index += 1;
int valueLen = *(int*)&data[index];
index += 4;
if (data[index + valueLen] != (uint8_t)DataPachKey::ValueEnd)
return;
this->Value.assign(&data[index], &data[index + valueLen]);
index += valueLen + 1;
break;
}
case DataPachKey::ValueStart_Small:
{
index += 1;
uint16_t valueLen = *(uint16_t*)&data[index];
index += 2;
if (data[index + valueLen] != (uint8_t)DataPachKey::ValueEnd)
return;
this->Value.assign(&data[index], &data[index + valueLen]);
index += valueLen + 1;
break;
}
case DataPachKey::ValueStart_Small_X:
{
index += 1;
uint8_t valueLen = *(uint8_t*)&data[index];
index += 1;
if (data[index + valueLen] != (uint8_t)DataPachKey::ValueEnd)
return;
this->Value.assign(&data[index], &data[index + valueLen]);
index += valueLen + 1;
break;
}
case DataPachKey::ChildStart:
{
index += 1;
int childLen = *(int*)&data[index];
index += 4;
if (data[index + childLen] != (uint8_t)DataPachKey::ChildEnd)
return;
DataPack childPack(&data[index], childLen);
this->Child.push_back(childPack);
index += childLen + 1;
break;
}
case DataPachKey::ChildStart_Small:
{
index += 1;
uint16_t childLen = *(uint16_t*)&data[index];
index += 2;
if (data[index + childLen] != (uint8_t)DataPachKey::ChildEnd)
return;
DataPack childPack(&data[index], childLen);
this->Child.push_back(childPack);
index += childLen + 1;
break;
}
case DataPachKey::ChildStart_Small_X:
{
index += 1;
uint8_t childLen = *(uint8_t*)&data[index];
index += 1;
if (data[index + childLen] != (uint8_t)DataPachKey::ChildEnd)
return;
DataPack childPack(&data[index], childLen);
this->Child.push_back(childPack);
index += childLen + 1;
break;
}
default:
{
return;
}
}
}
}
DataPack::DataPack(const char* key)
{
this->Id = key;
this->Value.resize(0);
}
DataPack::DataPack(std::string id, uint8_t* data, int len)
{
this->Id = id;
this->Value.resize(len);
RtlCopyMemory(this->Value.data(), data, len);
}
DataPack::DataPack(std::vector<uint8_t> data) :DataPack(data.data(), data.size()) {}
DataPack::DataPack(std::initializer_list<uint8_t> data) :DataPack((uint8_t*)data.begin(), data.size()) {}
DataPack::DataPack(std::string id, std::string data)
{
this->Id = id;
this->Value.resize(data.size());
memcpy(this->Value.data(), data.c_str(), data.size());
}
DataPack::DataPack(std::string id, std::wstring data)
{
this->Id = id;
this->Value.resize(data.size() * 2);
memcpy(this->Value.data(), data.c_str(), data.size() * 2);
}
DataPack::DataPack(std::string id, char* data)
{
this->Id = id;
std::string str = data;
this->Value.resize(str.size());
memcpy(this->Value.data(), str.c_str(), str.size());
}
DataPack::DataPack(std::string id, const char* data)
{
this->Id = id;
std::string str = data;
this->Value.resize(str.size());
memcpy(this->Value.data(), str.c_str(), str.size());
}
DataPack::DataPack(std::string id, wchar_t* data)
{
this->Id = id;
std::wstring str = data;
this->Value.resize(str.size() * 2);
memcpy(this->Value.data(), str.c_str(), str.size() * 2);
}
DataPack::DataPack(std::string id, const wchar_t* data)
{
this->Id = id;
std::wstring str = data;
this->Value.resize(str.size() * 2);
memcpy(this->Value.data(), str.c_str(), str.size() * 2);
}
void DataPack::Add(DataPack val)
{
this->Child.push_back(val);
}
void DataPack::clear()
{
this->Child.clear();
}
int DataPack::size()
{
return this->Child.size();
}
std::vector<uint8_t> DataPack::GetBytes()
{
std::vector<uint8_t> list = std::vector<uint8_t>(1);
list[0] = (uint8_t)DataPachKey::FileStart;
if (this->Id.size() > 0)
{
list.resize(6);
list[5] = (uint8_t)DataPachKey::IdStart;
uint16_t idlen = this->Id.size();
list.insert(list.end(), (uint8_t*)&idlen, (uint8_t*)&idlen + 2);
list.insert(list.end(), this->Id.c_str(), this->Id.c_str() + this->Id.size());
list.push_back((uint8_t)DataPachKey::IdEnd);
}
else
{
list.resize(5);
}
if (this->Value.size() > 0)
{
if (this->Value.size() > UINT16_MAX)
{
list.push_back((uint8_t)DataPachKey::ValueStart);
int vvlen = this->Value.size();
list.insert(list.end(), (uint8_t*)&vvlen, (uint8_t*)&vvlen + 4);
}
else
{
if (this->Value.size() > UINT8_MAX)
{
list.push_back((uint8_t)DataPachKey::ValueStart_Small);
uint16_t vvlen = this->Value.size();
list.insert(list.end(), (uint8_t*)&vvlen, (uint8_t*)&vvlen + 2);
}
else
{
list.push_back((uint8_t)DataPachKey::ValueStart_Small_X);
uint8_t vvlen = this->Value.size();
list.insert(list.end(), (uint8_t*)&vvlen, (uint8_t*)&vvlen + 1);
}
}
list.insert(list.end(), this->Value.data(), this->Value.data() + this->Value.size());
list.push_back((uint8_t)DataPachKey::ValueEnd);
}
for (auto sub : this->Child)
{
auto dta = sub.GetBytes();
if (dta.size() > UINT16_MAX)
{
list.push_back((uint8_t)DataPachKey::ChildStart);
int childLen = dta.size();
list.insert(list.end(), (uint8_t*)&childLen, (uint8_t*)&childLen + 4);
}
else
{
if (dta.size() > UINT8_MAX)
{
list.push_back((uint8_t)DataPachKey::ChildStart_Small);
uint16_t childLen = dta.size();
list.insert(list.end(), (uint8_t*)&childLen, (uint8_t*)&childLen + 2);
}
else
{
list.push_back((uint8_t)DataPachKey::ChildStart_Small_X);
uint8_t childLen = dta.size();
list.insert(list.end(), (uint8_t*)&childLen, (uint8_t*)&childLen + 1);
}
}
list.insert(list.end(), dta.data(), dta.data() + dta.size());
list.push_back((uint8_t)DataPachKey::ChildEnd);
}
list.push_back((uint8_t)DataPachKey::FileEnd);
*(int*)&list[1] = list.size();
return list;
}