
Tomas, ----- Original Message ----- From: "Tomas Puverle" <Tomas.Puverle@morganstanley.com> Newsgroups: gmane.comp.lib.boost.devel To: <boost@lists.boost.org> 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