MADARA  3.4.1
ReducedMessageHeader.cpp
Go to the documentation of this file.
1 
2 #include <algorithm>
3 #include <string.h>
4 #include <sstream>
5 
7 #include "ReducedMessageHeader.h"
9 
11  : MessageHeader()
12 {
13  memcpy(madara_id, REDUCED_MADARA_ID, 7);
14  madara_id[7] = 0;
15 }
16 
18 
20 {
21  return sizeof(uint64_t) * 3 // size, clock, timestamp
22  + sizeof(char) * (MADARA_IDENTIFIER_LENGTH + 1) // KaRL1.0 + ttl
23  + sizeof(uint32_t) * 1; // updates
24 }
25 
27  const char* buffer, int64_t& buffer_remaining)
28 {
29  // Remove size field from the buffer and update accordingly
30  if ((size_t)buffer_remaining >= sizeof(size))
31  {
32  memcpy(&size, buffer, sizeof(size));
33  size = madara::utility::endian_swap(size);
34  buffer += sizeof(size);
35  }
36  else
37  {
38  std::stringstream buffer;
39  buffer << "ReducedMessageHeader::read: ";
40  buffer << sizeof(size) << " byte size encoding cannot";
41  buffer << " fit in ";
42  buffer << buffer_remaining << " byte buffer\n";
43 
44  throw exceptions::MemoryException(buffer.str());
45  }
46  buffer_remaining -= sizeof(size);
47 
48  // Remove madara_id field from the buffer and update accordingly
49  if ((size_t)buffer_remaining >= sizeof(char) * MADARA_IDENTIFIER_LENGTH)
50  {
52  buffer += sizeof(char) * MADARA_IDENTIFIER_LENGTH;
53  }
54  else
55  {
56  std::stringstream buffer;
57  buffer << "ReducedMessageHeader::read: ";
58  buffer << MADARA_IDENTIFIER_LENGTH << " byte id encoding cannot";
59  buffer << " fit in ";
60  buffer << buffer_remaining << " byte buffer\n";
61 
62  throw exceptions::MemoryException(buffer.str());
63  }
64  buffer_remaining -= sizeof(char) * MADARA_IDENTIFIER_LENGTH;
65 
66  // Remove updates field from the buffer and update accordingly
67  if ((size_t)buffer_remaining >= sizeof(updates))
68  {
69  memcpy(&updates, buffer, sizeof(updates));
70  updates = madara::utility::endian_swap(updates);
71  buffer += sizeof(updates);
72  }
73  else
74  {
75  std::stringstream buffer;
76  buffer << "ReducedMessageHeader::read: ";
77  buffer << sizeof(updates) << " byte updates encoding cannot";
78  buffer << " fit in ";
79  buffer << buffer_remaining << " byte buffer\n";
80 
81  throw exceptions::MemoryException(buffer.str());
82  }
83  buffer_remaining -= sizeof(updates);
84 
85  // Remove clock field from the buffer and update accordingly
86  if ((size_t)buffer_remaining >= sizeof(clock))
87  {
88  memcpy(&clock, buffer, sizeof(clock));
89  clock = madara::utility::endian_swap(clock);
90  buffer += sizeof(clock);
91  }
92  else
93  {
94  std::stringstream buffer;
95  buffer << "ReducedMessageHeader::read: ";
96  buffer << sizeof(clock) << " byte clock encoding cannot";
97  buffer << " fit in ";
98  buffer << buffer_remaining << " byte buffer\n";
99 
100  throw exceptions::MemoryException(buffer.str());
101  }
102  buffer_remaining -= sizeof(clock);
103 
104  // Remove timestamp field from the buffer and update accordingly
105  if ((size_t)buffer_remaining >= sizeof(timestamp))
106  {
107  memcpy(&timestamp, buffer, sizeof(timestamp));
108  timestamp = madara::utility::endian_swap(timestamp);
109  buffer += sizeof(timestamp);
110  }
111  else
112  {
113  std::stringstream buffer;
114  buffer << "ReducedMessageHeader::read: ";
115  buffer << sizeof(timestamp) << " byte timestamp encoding cannot";
116  buffer << " fit in ";
117  buffer << buffer_remaining << " byte buffer\n";
118 
119  throw exceptions::MemoryException(buffer.str());
120  }
121  buffer_remaining -= sizeof(timestamp);
122 
123  // Remove the time to live field from the buffer
124  if (buffer_remaining >= 1)
125  {
126  memcpy(&ttl, buffer, 1);
127  buffer += 1;
128  }
129  buffer_remaining -= 1;
130 
131  return buffer;
132 }
133 
135  char* buffer, int64_t& buffer_remaining)
136 {
137  // Write size field from the buffer and update accordingly
138  if ((size_t)buffer_remaining >= sizeof(size))
139  {
140  *(uint64_t*)buffer = madara::utility::endian_swap(size);
141  buffer += sizeof(size);
142  }
143  else
144  {
145  std::stringstream buffer;
146  buffer << "ReducedMessageHeader::write: ";
147  buffer << sizeof(size) << " byte size encoding cannot";
148  buffer << " fit in ";
149  buffer << buffer_remaining << " byte buffer\n";
150 
151  throw exceptions::MemoryException(buffer.str());
152  }
153  buffer_remaining -= sizeof(size);
154 
155  // Write madara_id field from the buffer and update accordingly
156  if ((size_t)buffer_remaining >= sizeof(char) * MADARA_IDENTIFIER_LENGTH)
157  {
159  buffer += sizeof(char) * MADARA_IDENTIFIER_LENGTH;
160  }
161  else
162  {
163  std::stringstream buffer;
164  buffer << "ReducedMessageHeader::write: ";
165  buffer << MADARA_IDENTIFIER_LENGTH << " byte id encoding cannot";
166  buffer << " fit in ";
167  buffer << buffer_remaining << " byte buffer\n";
168 
169  throw exceptions::MemoryException(buffer.str());
170  }
171  buffer_remaining -= sizeof(char) * MADARA_IDENTIFIER_LENGTH;
172 
173  // Write updates field from the buffer and update accordingly
174  if ((size_t)buffer_remaining >= sizeof(updates))
175  {
176  *(uint32_t*)buffer = madara::utility::endian_swap(updates);
177  buffer += sizeof(updates);
178  }
179  else
180  {
181  std::stringstream buffer;
182  buffer << "ReducedMessageHeader::write: ";
183  buffer << sizeof(updates) << " byte updates encoding cannot";
184  buffer << " fit in ";
185  buffer << buffer_remaining << " byte buffer\n";
186 
187  throw exceptions::MemoryException(buffer.str());
188  }
189  buffer_remaining -= sizeof(updates);
190 
191  // Write clock field from the buffer and update accordingly
192  if ((size_t)buffer_remaining >= sizeof(clock))
193  {
194  *(uint64_t*)buffer = madara::utility::endian_swap(clock);
195  buffer += sizeof(clock);
196  }
197  else
198  {
199  std::stringstream buffer;
200  buffer << "ReducedMessageHeader::write: ";
201  buffer << sizeof(clock) << " byte clock encoding cannot";
202  buffer << " fit in ";
203  buffer << buffer_remaining << " byte buffer\n";
204 
205  throw exceptions::MemoryException(buffer.str());
206  }
207  buffer_remaining -= sizeof(clock);
208 
209  // Write timestamp field from the buffer and update accordingly
210  if ((size_t)buffer_remaining >= sizeof(timestamp))
211  {
212  *(uint64_t*)buffer = madara::utility::endian_swap(timestamp);
213  buffer += sizeof(timestamp);
214  }
215  else
216  {
217  std::stringstream buffer;
218  buffer << "ReducedMessageHeader::write: ";
219  buffer << sizeof(timestamp) << " byte timestamp encoding cannot";
220  buffer << " fit in ";
221  buffer << buffer_remaining << " byte buffer\n";
222 
223  throw exceptions::MemoryException(buffer.str());
224  }
225  buffer_remaining -= sizeof(timestamp);
226 
227  // Write the time to live field
228  if (buffer_remaining >= 1)
229  {
230  memcpy(buffer, &ttl, 1);
231  buffer += 1;
232  }
233  buffer_remaining -= 1;
234 
235  return buffer;
236 }
237 
239 {
240  std::stringstream buffer;
241  buffer << "29: size (8:" << size << "), ";
242  buffer << "encoding (8:" << madara_id << "), ";
243  buffer << "numupdates (4:" << updates << "), ";
244  buffer << "clock (8:" << clock << "), ";
245  buffer << "ttl (1:" << ttl << "), ";
246 
247  return buffer.str();
248 }
249 
251 {
252  return size == other.size && updates == other.updates &&
253  clock == other.clock && timestamp == other.timestamp;
254 }
#define MADARA_IDENTIFIER_LENGTH
Definition: MessageHeader.h:21
#define REDUCED_MADARA_ID
An exception for general memory errors like out-of-memory.
Defines a robust message header which is the default for KaRL messages.
Definition: MessageHeader.h:57
uint64_t timestamp
the timestamp of the sender when the message was generated
uint32_t updates
the number of knowledge variable updates in the message
uint64_t clock
the clock of the sender when the message was generated
uint64_t size
the size of this header plus the updates
char madara_id[8]
the identifier of this transport (MADARA_IDENTIFIER)
virtual const char * read(const char *buffer, int64_t &buffer_remaining)
Reads a MessageHeader instance from a buffer and updates the amount of buffer room remaining.
virtual char * write(char *buffer, int64_t &buffer_remaining)
Writes a MessageHeader instance to a buffer and updates the amount of buffer room remaining.
virtual uint32_t encoded_size(void) const
Returns the size of the encoded MessageHeader class, which may be different from sizeof (MessageHeade...
virtual bool equals(const MessageHeader &other)
Compares the fields of this instance to another instance.
virtual std::string to_string(void)
Converts the relevant fields to a printable string.
constexpr string_t string
uint64_t endian_swap(uint64_t value)
Converts a host format uint64_t into big endian.
Definition: Utility.inl:134
MADARA_EXPORT void strncpy_safe(char *dst, const char *src, size_t dst_size)
Performs a strncpy in a way that will compile without warnings.
Definition: Utility.cpp:376