简体   繁体   中英

Read/write binary object as hex?

I need to serialize various structs to a file. If possible I'd like the files to be pure ASCII. I could write some kind of serializer for each struct, but there are hundreds and many contain float s and double s which I'd like to represent accurately.

I can't use a third-party serialization library and I don't have the time to write hundreds of serializiers.

How can I ASCII-safe serialize this data? Also streams please, I hate the look of C-style printf("%02x",data) .

I found this solution online and it addresses just this problem:

https://jdale88.wordpress.com/2009/09/24/c-anything-tofrom-a-hex-string/

Reproduced below:

#include <string>
#include <sstream>
#include <iomanip>


// ------------------------------------------------------------------
/*!
    Convert a block of data to a hex string
*/
void toHex(
    void *const data,                   //!< Data to convert
    const size_t dataLength,            //!< Length of the data to convert
    std::string &dest                   //!< Destination string
    )
{
    unsigned char       *byteData = reinterpret_cast<unsigned char*>(data);
    std::stringstream   hexStringStream;

    hexStringStream << std::hex << std::setfill('0');
    for(size_t index = 0; index < dataLength; ++index)
        hexStringStream << std::setw(2) << static_cast<int>(byteData[index]);
    dest = hexStringStream.str();
}


// ------------------------------------------------------------------
/*!
    Convert a hex string to a block of data
*/
void fromHex(
    const std::string &in,              //!< Input hex string
    void *const data                    //!< Data store
    )
{
    size_t          length      = in.length();
    unsigned char   *byteData   = reinterpret_cast<unsigned char*>(data);

    std::stringstream hexStringStream; hexStringStream >> std::hex;
    for(size_t strIndex = 0, dataIndex = 0; strIndex < length; ++dataIndex)
    {
        // Read out and convert the string two characters at a time
        const char tmpStr[3] = { in[strIndex++], in[strIndex++], 0 };

        // Reset and fill the string stream
        hexStringStream.clear();
        hexStringStream.str(tmpStr);

        // Do the conversion
        int tmpValue = 0;
        hexStringStream >> tmpValue;
        byteData[dataIndex] = static_cast<unsigned char>(tmpValue);
    }
}

This can be easily adapted to read/write to file streams, although the stringstream used in fromHex is still necessary, the conversion must be done two read characters at a time.

Any way you do it, you're going to need serialization code for each struct type. You can't just bit-copy a struct to the external world, and expect it to work.

And if you want pure ascii, don't bother with hex. For serializing float and double , set the output stream to scientific, and the precision to 8 for float , and 16 for double . (It will take a few more bytes, but it will actually work.)

For the rest: if the struct are written cleanly, according to some in house programming guidelines, and only contain basic types, you should be able to parse them directly. Otherwise, the simplest solution is generally to design a very simple descriptor language, describe each struct in it, and run a code generator over it to get the serialization code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM