将一个结构体里面的数据转为 小端对齐的二进制流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 ********************************/