|
Boost : |
Subject: Re: [boost] [boost::endian] Request for comments/interest
From: Terry Golubiewski (tjgolubi_at_[hidden])
Date: 2010-05-30 12:54:23
Tomas,
----- Original Message -----
From: "Tomas Puverle" <Tomas.Puverle_at_[hidden]>
Newsgroups: gmane.comp.lib.boost.devel
To: <boost_at_[hidden]>
Sent: Sunday, May 30, 2010 10:27 AM
Subject: Re: [boost::endian] Request for comments/interest
>> struct UserMessage {
>> endian<little, time_point<system_clock, duration<int64_t, nano> > >
>> timestamp;
>
> I was under the impression that Beman's library doesn't support any types
> beside integers? This definitely looks like a user defined type to me.
I'm not referring to Beman's endian. I'm referring to "mine" that I posted
in an attachment in this thread on May 27.
It is still basically Beman's approach with all the integer dependence
removed. It provides endian<endian_t, T> where T could be any
over-the-wire-sendable type (i.e. no pointers, virtual members, etc).
>> struct Position {
>> endian<little, quantity<si::length, int32_t> > x;
>> endian<little, quantity<si::length, int32_t> > y;
>> endian<little, quantity<si::length, int32_t> > z;
>> } position;
>
> Again, UDTs?
Yep!
>> struct Packet {
>> internet::IpHeader ipHeader;
>> internet::UdpHeader udpHeader;
>> UserMessage userMessage;
>> }; // Packet
>> #pragma pack(pop)
>>
>> int main() {
>> Packet packet;
>> packet.ipHeader.source_address = 0x12345678;
>> packet.udpHeader.destination_port = 1234;
>> packet.userMessage.timestamp = system_clock::now();
>> packet.userMessage.position.y = 17 * si::meter;
>> } // main
>
> I definitely see the elegance of this code and as I said before, I am not
> opposed to implementing the typed interface. Having said that, I do have
> several concerns with how this gets actually read from/sent to a device
> and
> additionally, as mentioned in another post, I think this "neat" code may
> be a
> little opaque for someone not familiar with it.
I think the "opaqueness" is a major feature of this approach. The user of
the higher-level classes has no idea about the underlying endianness of the
message fields or if they've been byte-swapped yet or not. It just works.
And if the systems engineers later decided to change some of the endianness
of some of the message fields, the message definition code would change, but
none of the code that uses the messages would have to change at all.
Please let's address these device interface read/write concerns with a
concrete example.
For the example above, on the receiving end, to determine the time delay
between sender and receiver, the following code could be used (assuming
system_clock's are synced).
char buf[BIG_ENOUGH];
size_t bytesRead = device.read(buf, sizeof(buf));
assert(bytesRead >= sizeof(Packet));
const Packet& packet = *reinterpret_cast<const Packet*>(buf);
system_clock::duration delay = system_clock::now() -
packet.userMessage.timestamp;
On the sending end...
Packet packet;
// load the packet with stuff
packet.userMessage.timestamp = system_clock::now();
device.send(&packet, sizeof(packet));
Of course, I'm just showing one field for simplicity. Setting/getting the
other fields would be done similarly.
How would this example best be done with your library?
terry
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk