从xml读取结构体的成员值通用版

#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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值