I am current developing a C++11 library for an existing network remote control interface described in an Interface Control Document (ICD).
The interface is based on TCP/IPv4 and uses Network Byte Order (aka Big Endian).
Requirement: The library shall be developed cross-platform.
Note: I want to develop a solution without (ab)using the preprocessor.
After a short research on the WWW I discovered Boost.Endian which solves problems related to endianess of multi-byte data types. My approach is as follows:
- Serialize the (multi-)byte data types to a stream via
std::basic_ostream::write, more precisely via
os.write(reinterpret_cast<char const *>(&kData), sizeof(kData))
. - Convert the
std::basic_ostream
to astd::vector<std::uint8_t>
. - Send the
std::vector<std::uint8_t>
via Boost.Asio over the network.
So far so good. Everything seems to work as intended and the solution should be platform independent.
Now comes the tricky part: The ICD describes messages consisting of multiple words and a word consists of 8 bits. A message can contain multiple fields and a field does not have to be byte-aligned, which means that one word can contain multiple fields.
Example: Consider the following message format (the message body starts at word 10):
Word | Bit(s) | Name
-----|--------|----------
10 | 0-2 | a
10 | 3 | b
10 | 4 | c
10 | 5 | d
10 | 6 | e
10 | 7 | RESERVED
11 | 16 | f
and so on...
So now I need a solution to be able to model and serialize a bit-based interface.
I have looked at the following approaches so far:
Code:
// Using a arithmetic type from the `boost::endian` namespace does not work.
using Byte = std::uint8_t;
using BitSet = boost::dynamic_bitset<Byte>;
BitSet bitSetForA{3, 1};
BitSet bitSetForB{1};
// [...]
BitSet bitSetForF{16, 0x400}; // 1024
So, the 1024 in the example above is always serialized to 00 04
instead of
04 00
on my machine.
I really do not know what's the most pragmatic approach to solve my problem. Maybe you can guide me into the correct direction.
In conclusion I do need a recipe to implement an existing network interface defining bit fields in a platform-independent way with respect to the native byte order of the machine the library has been compiled on.