HSchmale
HSchmale

Reputation: 1929

How to convert a long long to a binary character string?

How can I convert a long long to an array of char's that match up in the binary values? I'm working on a program where a binary string is sent over a network to control a lighting system. The way I have it set up now is I have a function that receives an std::string, then sends that to the clients. I would really like to keep this architecture (std::strings are easy to pass back and forth)?

Edit: I'm looking for a binary serialization of a long long type as an array of bytes.

Upvotes: 1

Views: 874

Answers (2)

ThreeStarProgrammer57
ThreeStarProgrammer57

Reputation: 3044

If you don't mind using raw char array, you could simply go for:

char c[sizeof (long long)];
memcpy(c, &longlongValue, sizeof (long long));

edit:

or even:

char c[sizeof (long long)];
*(long long*)c = longlongValue;

which will probably be faster than a call to memcpy.

I agree this is not pretty c++, or c for that matter.

Upvotes: 2

amdn
amdn

Reputation: 11582

One thing you might consider is that the client and server on the network may have different endianness.

The Internet Protocol defines big-endian as the standard network byte order used for all numeric values in the packet headers and by many higher level protocols and file formats that are designed for use over IP. The Berkeley sockets API defines a set of functions to convert 16-bit and 32-bit integers to and from network byte order: the htons (host-to-network-short) and htonl (host-to-network-long) functions convert 16-bit and 32-bit values respectively from machine (host) to network order; the ntohs and ntohl functions convert from network to host order. These functions may be a no-op on a big-endian system.

network byte order, that is, big-endian. There is no standard library call to convert long long to and from network-byte-order. Following are some templates that can be used to serialize and deserialize any integral type to and from a std::string in network-byte-order. Live demo here.

To serialize

template< typename T >
string serialize( T val ) {
    string str( sizeof(T), 0 );
    for(size_t i=0; i<sizeof(T); ++i, val >>= 8)
        str[sizeof(T)-i-1] = char(val);
    return str;
}

To deserialize

template< typename T >
T deserialize( const string & data ) {
    T val = 0;
    for(unsigned char u : data) val = (val << 8) | u;
    return val;
}

And use it like this

long long val = 201501210654;
std::string str = serialize(val);
assert( val == deserialize<long long>( str ) );

Upvotes: 1

Related Questions