5 #ifndef GCOMM_DATAGRAM_HPP
6 #define GCOMM_DATAGRAM_HPP
8 #include "gu_buffer.hpp"
9 #include "gu_serialize.hpp"
10 #include "gu_utils.hpp"
41 static checksum_t checksum_type (
int i);
55 gu_throw_error(EINVAL) <<
"msg too long " << len_;
56 len_ |= (
static_cast<uint32_t
>(version) << version_shift_);
59 uint32_t len()
const {
return (len_ & len_mask_); }
61 void set_crc32(uint32_t crc32, checksum_t type)
63 assert (CS_CRC32 == type || CS_CRC32C == type);
65 CS_CRC32 == type ? len_ |= F_CRC32 : len_ |= F_CRC32C;
68 bool has_crc32()
const {
return (len_ & F_CRC32); }
69 bool has_crc32c()
const {
return (len_ & F_CRC32C); }
71 uint32_t crc32()
const {
return crc32_; }
75 return ((len_ & version_mask_) >> version_shift_);
78 friend size_t serialize(
const NetHeader& hdr, gu::byte_t* buf,
79 size_t buflen,
size_t offset);
81 friend size_t unserialize(
const gu::byte_t* buf,
size_t buflen,
84 friend size_t serial_size(
const NetHeader& hdr);
86 static const size_t serial_size_ = 8;
90 static const uint32_t len_mask_ = 0x00ffffff;
91 static const uint32_t flags_mask_ = 0x0f000000;
92 static const uint32_t flags_shift_ = 24;
93 static const uint32_t version_mask_ = 0xf0000000;
94 static const uint32_t version_shift_ = 28;
106 inline size_t serialize(
const NetHeader& hdr, gu::byte_t* buf,
107 size_t buflen,
size_t offset)
109 offset = gu::serialize4(hdr.len_, buf, buflen, offset);
110 offset = gu::serialize4(hdr.crc32_, buf, buflen, offset);
114 inline size_t unserialize(
const gu::byte_t* buf,
size_t buflen,
115 size_t offset, NetHeader& hdr)
117 offset = gu::unserialize4(buf, buflen, offset, hdr.len_);
118 offset = gu::unserialize4(buf, buflen, offset, hdr.crc32_);
120 switch (hdr.version())
123 if ((hdr.len_ & NetHeader::flags_mask_) &
124 ~(NetHeader::F_CRC32 | NetHeader::F_CRC32C))
126 gu_throw_error(EPROTO)
128 << ((hdr.len_ & NetHeader::flags_mask_) >>
129 NetHeader::flags_shift_);
133 gu_throw_error(EPROTO) <<
"invalid protocol version "
140 inline size_t serial_size(
const NetHeader& hdr)
142 return NetHeader::serial_size_;
157 header_offset_(header_size_),
158 payload_ (
new gu::Buffer()),
173 header_offset_(header_size_),
174 payload_ (new gu::Buffer(buf)),
177 assert(offset_ <= payload_->size());
180 Datagram(
const gu::SharedBuffer& buf,
size_t offset = 0)
183 header_offset_(header_size_),
187 assert(offset_ <= payload_->size());
200 size_t off = std::numeric_limits<size_t>::max()) :
202 header_offset_(dgram.header_offset_),
203 payload_(dgram.payload_),
204 offset_(off == std::numeric_limits<size_t>::max() ? dgram.offset_ : off)
206 assert(offset_ <= dgram.len());
207 memcpy(header_ + header_offset_,
208 dgram.header_ + dgram.header_offset(),
219 const gu::SharedBuffer old_payload(payload_);
220 payload_ = gu::SharedBuffer(
new gu::Buffer);
221 payload_->reserve(header_len() + old_payload->size() - offset_);
223 if (header_len() > offset_)
225 payload_->insert(payload_->end(),
226 header_ + header_offset_ + offset_,
227 header_ + header_size_);
232 offset_ -= header_len();
234 header_offset_ = header_size_;
235 payload_->insert(payload_->end(), old_payload->begin() + offset_,
240 gu::byte_t* header() {
return header_; }
241 const gu::byte_t* header()
const {
return header_; }
242 size_t header_size()
const {
return header_size_; }
243 size_t header_len()
const {
return (header_size_ - header_offset_); }
244 size_t header_offset()
const {
return header_offset_; }
246 void set_header_offset(
const size_t off)
249 if (off > header_size_) gu_throw_fatal <<
"out of hdrspace";
250 header_offset_ = off;
253 const gu::Buffer& payload()
const
255 assert(payload_ != 0);
259 gu::Buffer& payload()
261 assert(payload_ != 0);
267 return (header_size_ - header_offset_ + payload_->size());
270 size_t offset()
const {
return offset_; }
274 friend uint16_t crc16(
const Datagram&,
size_t);
275 friend uint32_t crc32(NetHeader::checksum_t,
const Datagram&,
size_t);
277 static const size_t header_size_ = 128;
278 gu::byte_t header_[header_size_];
279 size_t header_offset_;
280 gu::SharedBuffer payload_;
284 uint16_t crc16(
const Datagram& dg,
size_t offset = 0);
285 uint32_t crc32(NetHeader::checksum_t type,
const Datagram& dg,
289 inline bool check_cs (
const NetHeader& hdr,
const Datagram& dg)
291 if (hdr.has_crc32c())
292 return (crc32(NetHeader::CS_CRC32C, dg) != hdr.crc32());
295 return (crc32(NetHeader::CS_CRC32, dg) != hdr.crc32());
297 return (hdr.crc32() != 0);
301 #endif // GCOMM_DATAGRAM_HPP
~Datagram()
Destruct datagram.
Definition: datagram.hpp:215
Datagram(const gu::Buffer &buf, size_t offset=0)
Construct new datagram from byte buffer.
Definition: datagram.hpp:170
Datagram(const Datagram &dgram, size_t off=std::numeric_limits< size_t >::max())
Copy constructor.
Definition: datagram.hpp:199
Datagram container.
Definition: datagram.hpp:151