348 lines
8.4 KiB
C++
348 lines
8.4 KiB
C++
#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;
|
|
} |