Reputation: 1929
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::string
s 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
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
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