#ifndef _READSTRUCT_H_
#define _READSTRUCT_H_
#include <vector>
#include <string>
#include <map>
#include "tinyxml2.h"
std::map<std::string, const size_t> dataTypeSizeMap = {
{"char", sizeof(char)},
{"short", sizeof(short)},
{"int", sizeof(int)},
{"unsigned", sizeof(unsigned)},
{"long", sizeof(long)},
{"unsigned long", sizeof(unsigned long)},
{"long long", sizeof(long long)},
{"unsigned long long", sizeof(unsigned long long)},
{"float", sizeof(float)},
{"double", sizeof(double)},
{"long double", sizeof(long double)},
{"bool", sizeof(bool)}};
bool SplitString(const char *&pStr, size_t pStrSize, std::vector<std::string> &pStrVec, const char pseparator = ',')
{
if (NULL == pStr || 0 == pStrSize)
{
return false;
}
pStrVec.clear();
size_t pos1 = 0;
size_t pos2 = 0;
for (; pos2 != pStrSize; pos2++)
{
if (pseparator == pStr[pos2])
{
char tempStr[256] = {0};
std::memcpy(&tempStr[0], pStr + pos1, pos2 - pos1);
pStrVec.push_back(std::string(tempStr));
pos1 = pos2 + 1;
}
}
if (pos2 != pos1)
{
char tempStr[20] = {0};
std::memcpy(&tempStr[0], pStr + pos1, pos2 - pos1);
pStrVec.push_back(std::string(tempStr));
}
return true;
}
void readStruct(tinyxml2::XMLElement *pRootEle, char *pStructByte, size_t &pCurrentSize)
{
if (0 != strcmp(pRootEle->Attribute("DataType"), "struct"))
{
return;
}
const size_t maxMemberDataTypeSize = dataTypeSizeMap[std::string(pRootEle->Attribute("MaxSizeDataType"))];
size_t firstMoveSize =
(0 == pCurrentSize % maxMemberDataTypeSize) ? 0 : maxMemberDataTypeSize - pCurrentSize % maxMemberDataTypeSize;
pStructByte += firstMoveSize;
pCurrentSize += firstMoveSize;
tinyxml2::XMLElement *pChildEle = pRootEle->FirstChildElement();
while (NULL != pChildEle)
{
const char *datatype = pChildEle->Attribute("DataType");
const char *text = pChildEle->GetText();
if (0 != strcmp(datatype, "struct") && NULL == text)
{
pChildEle = pChildEle->NextSiblingElement();
continue;
}
size_t maxDataCount = 1;
const char *strMaxDataCount = pChildEle->Attribute("MaxDataCount");
if (NULL != strMaxDataCount)
{
maxDataCount = std::atoi(strMaxDataCount);
if (maxDataCount < 1)
{
maxDataCount = 1;
}
}
size_t appendingSize = 0;
if (0 == strcmp(datatype, "char"))
{
if (NULL != text)
{
std::memcpy(pStructByte, text, std::strlen(text));
}
pStructByte += maxDataCount;
pCurrentSize += appendingSize + maxDataCount;
}
else
{
if (0 == strcmp(datatype, "struct"))
{
readStruct(pChildEle, pStructByte, pCurrentSize);
}
else
{
std::vector<std::string> strVec;
if (NULL != text)
{
SplitString(text, std::strlen(text), strVec);
}
if (0 == strcmp(datatype, "short"))
{
size_t dataTypeSize = sizeof(short);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
short value = 0;
char *end = NULL;
for (size_t i = 0; i < strVec.size(); i++)
{
value = std::strtol(text, &end, 10);
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
}
pStructByte += dataTypeSize * (maxDataCount - strVec.size());
pCurrentSize += appendingSize + dataTypeSize * maxDataCount;
}
else if (0 == strcmp(datatype, "int"))
{
size_t dataTypeSize = sizeof(int);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
int value = 0;
char *end = NULL;
for (size_t i = 0; i < strVec.size(); i++)
{
value = std::strtol(text, &end, 10);
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
}
pStructByte += dataTypeSize * (maxDataCount - strVec.size());
pCurrentSize += appendingSize + dataTypeSize * maxDataCount;
}
else if (0 == strcmp(datatype, "unsigned"))
{
size_t dataTypeSize = sizeof(unsigned);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
unsigned value = 0;
char *end = NULL;
for (size_t i = 0; i < strVec.size(); i++)
{
value = std::strtoul(text, &end, 10);
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
}
pStructByte += dataTypeSize * (maxDataCount - strVec.size());
pCurrentSize += appendingSize + dataTypeSize * maxDataCount;
}
else if (0 == strcmp(datatype, "long"))
{
size_t dataTypeSize = sizeof(long);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
long value = 0;
char *end = NULL;
for (size_t i = 0; i < strVec.size(); i++)
{
value = std::strtol(text, &end, 10);
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
}
pStructByte += dataTypeSize * (maxDataCount - strVec.size());
pCurrentSize += appendingSize + dataTypeSize * maxDataCount;
}
else if (0 == strcmp(datatype, "unsigned long"))
{
size_t dataTypeSize = sizeof(unsigned long);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
unsigned long value = 0;
char *end = NULL;
for (size_t i = 0; i < strVec.size(); i++)
{
value = std::strtoul(text, &end, 10);
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
}
pStructByte += dataTypeSize * (maxDataCount - strVec.size());
pCurrentSize += appendingSize + dataTypeSize * maxDataCount;
}
else if (0 == strcmp(datatype, "long long"))
{
size_t dataTypeSize = sizeof(long long);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
long long value = 0;
char *end = NULL;
for (size_t i = 0; i < strVec.size(); i++)
{
value = std::strtoll(text, &end, 10);
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
}
pStructByte += dataTypeSize * (maxDataCount - strVec.size());
pCurrentSize += appendingSize + dataTypeSize * maxDataCount;
}
else if (0 == strcmp(datatype, "unsigned long long"))
{
size_t dataTypeSize = sizeof(unsigned long long);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
unsigned long long value = 0;
char *end = NULL;
for (size_t i = 0; i < strVec.size(); i++)
{
value = std::strtoull(text, &end, 10);
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
}
pStructByte += dataTypeSize * (maxDataCount - strVec.size());
pCurrentSize += appendingSize + dataTypeSize * maxDataCount;
}
else if (0 == strcmp(datatype, "float"))
{
size_t dataTypeSize = sizeof(float);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
float value = 0;
char *end = NULL;
for (size_t i = 0; i < strVec.size(); i++)
{
value = std::strtof(text, &end);
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
}
pStructByte += dataTypeSize * (maxDataCount - strVec.size());
pCurrentSize += appendingSize + dataTypeSize * maxDataCount;
}
else if (0 == strcmp(datatype, "double"))
{
size_t dataTypeSize = sizeof(double);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
double value = 0;
char *end = NULL;
for (size_t i = 0; i < strVec.size(); i++)
{
value = std::strtod(text, &end);
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
}
pStructByte += dataTypeSize * (maxDataCount - strVec.size());
pCurrentSize += appendingSize + dataTypeSize * maxDataCount;
}
else if (0 == strcmp(datatype, "long double"))
{
size_t dataTypeSize = sizeof(long double);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
long double value = 0;
char *end = NULL;
for (size_t i = 0; i < strVec.size(); i++)
{
value = std::strtold(text, &end);
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
}
pStructByte += dataTypeSize * (maxDataCount - strVec.size());
pCurrentSize += appendingSize + dataTypeSize * maxDataCount;
}
else if (0 == strcmp(datatype, "bool"))
{
size_t dataTypeSize = sizeof(bool);
appendingSize = (0 == pCurrentSize % dataTypeSize) ? 0 : dataTypeSize - pCurrentSize % dataTypeSize;
pStructByte += appendingSize;
bool value = false;
value = (0 == strcmp(text, "true")) ? true : false;
std::memcpy(pStructByte, (char *)(&value), dataTypeSize);
pStructByte += dataTypeSize;
pCurrentSize += appendingSize + dataTypeSize;
}
}
}
pChildEle = pChildEle->NextSiblingElement();
}
}
void readStructFromXml(const char *pStr, char *pStructByte)
{
if (NULL == pStr || NULL == pStructByte)
{
return;
}
tinyxml2::XMLDocument doc;
doc.LoadFile(pStr);
tinyxml2::XMLElement *rootEle = doc.RootElement();
size_t currentSize = 0;
readStruct(rootEle, pStructByte, currentSize);
}
#endif
从xml读取结构体的成员值通用版
于 2022-03-21 10:07:33 首次发布