将一个结构体里面的数据转为 小端对齐的二进制流V2.0

结构体 转 小端对齐二进制流;

二进制流 转 结构体, V2.0版本;

这个版本 添加了要求。字符串长度要求是4的整数倍,不足的地方用0补齐。

 

#include <iostream>  
#include <vector>
#include <cstring>
#include <iomanip>

typedef struct tagInfoA {
    uint8_t    Ver;
    uint16_t   Code;
    uint8_t    Reserve;
    uint32_t   a;
    char       szBuf1[10];
} INFOA_DEF;

bool isLittleEndian() {
    uint32_t num = 0x01020304;
    uint8_t* ptr = reinterpret_cast<uint8_t*>(&num);
    return (*ptr == 0x04); // If the least significant byte (LSB) is 0x04, then it's little-endian
}

void appendLittleEndian(std::vector<uint8_t>& block, const void* data, size_t size) {
    const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
    for (size_t i = 0; i < size; ++i) {
        block.push_back(*ptr);
        ++ptr;
    }
}

template<typename T>
void parseLittleEndian(const std::vector<uint8_t>& block, size_t& offset, T& value) {
    std::memcpy(&value, &block[offset], sizeof(T));
    offset += sizeof(T);
}

void appendPaddedString(std::vector<uint8_t>& block, const char* str, size_t length, size_t paddedLength) {
    size_t len = std::strlen(str);
    if (len > length) {
        len = length;
    }
    block.insert(block.end(), str, str + len);
    for (size_t i = len; i < paddedLength; ++i) {
        block.push_back(0); // Padding with null bytes
    }
}

void parsePaddedString(const std::vector<uint8_t>& block, size_t& offset, char* str, size_t length) {
    std::memcpy(str, &block[offset], length);
    offset += length; // Offset increment
    str[length] = '\0'; // Ensure null-terminated string
}

void testAppend(){
    std::vector<uint8_t> block;
    INFOA_DEF test1;
    test1.Ver = 0x01;
    test1.Code = 0x0203;
    test1.Reserve = 0x04;
    test1.a = 0x0506;
    std::memcpy(test1.szBuf1, "abcde", 6); // Copy only 6 characters to leave space for null terminator

    // Convert struct to little-endian byte stream
    appendLittleEndian(block, &test1.Ver, sizeof(test1.Ver));
    appendLittleEndian(block, &test1.Code, sizeof(test1.Code));
    appendLittleEndian(block, &test1.Reserve, sizeof(test1.Reserve));
    appendLittleEndian(block, &test1.a, sizeof(test1.a));
    auto strLength = (0==strlen(test1.szBuf1)%4) ? strlen(test1.szBuf1) : (strlen(test1.szBuf1)/4+1)*4;
    appendPaddedString(block, test1.szBuf1, strlen(test1.szBuf1), strLength);//4的整数倍

    // Output binary stream
    std::cout << "Binary Stream in little-endian format:\n";
    for (uint8_t byte : block) {
        std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte) << " ";
    }
    std::cout << std::endl;
}

void testPrase(){
    std::vector<uint8_t> block={0x01,0x03, 0x02, 0x04, 0x06, 0x05, 0x00, 0x00, 
                                0x61, 0x62, 0x63, 0x64, 0x65, 0x00, 0x00, 0x00};
    // Parse binary stream back to struct
    size_t offset = 0;
    INFOA_DEF parsedData;
    parseLittleEndian(block, offset, parsedData.Ver);
    parseLittleEndian(block, offset, parsedData.Code);
    parseLittleEndian(block, offset, parsedData.Reserve);
    parseLittleEndian(block, offset, parsedData.a);
    auto strLength = (0==sizeof(parsedData.szBuf1)%4) ? sizeof(parsedData.szBuf1) : (sizeof(parsedData.szBuf1)/4+1)*4;
    parsePaddedString(block, offset, parsedData.szBuf1, strLength);//4的整数倍
    //std::memcpy(parsedData.szBuf1, &block[offset], sizeof(parsedData.szBuf1));
    //offset += sizeof(parsedData.szBuf1);

    // Output parsed struct
    std::cout << "\nParsed Data:\n";
    std::cout << "Ver: " << std::hex << static_cast<int>(parsedData.Ver) << std::endl;
    std::cout << "Code: " << std::hex << static_cast<int>(parsedData.Code) << std::endl;
    std::cout << "Reserve: " << std::hex << static_cast<int>(parsedData.Reserve) << std::endl;
    std::cout << "a: " << std::hex << parsedData.a << std::endl;
    std::cout << "szBuf1: " << parsedData.szBuf1 << std::endl;
}

int main() {  
    if (isLittleEndian()) {
        std::cout << "Current machine is little-endian.\n";
    } else {
        std::cout << "Current machine is big-endian.\n";
    }
    testAppend();
    testPrase();
    return 0;  
}

/********************************
Current machine is little-endian.
Binary Stream in little-endian format:
01 03 02 04 06 05 00 00 61 62 63 64 65 00 00 00 

Parsed Data:
Ver: 1
Code: 203
Reserve: 4
a: 506
szBuf1: abcde

********************************/

 

posted @ 2024-04-09 00:03  He_LiangLiang  阅读(12)  评论(0编辑  收藏  举报