c6cf4bf7cdeb6fef646dfe2334585caa3b00ba96
[chaz/yoink] / src / Moof / old / Packet.hh
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 /**
13 * \file Packet.hh
14 * Classes for building and interpreting datagram packets.
15 */
16
17 #ifndef _MOOF_PACKET_HH_
18 #define _MOOF_PACKET_HH_
19
20 #include <cstring>
21 #include <string>
22 #include <vector>
23
24
25 #ifndef PAGE_SIZE
26 #define PAGE_SIZE 4096
27 #endif
28
29
30 namespace Mf {
31
32
33 /**
34 * Represents a packet of serialized variables ready for transfer over the
35 * network. This method is most suitable for representing datagram
36 * packets, but it may also be useful for seralizing data for persistent
37 * state storage. The semantics are similar to that of a FIFO queue or
38 * stream where packets are written and read by inserting and extracting
39 * variables to and from the packet, although the actual order of the
40 * variables in the buffer may be different. At any time, a pointer to a
41 * buffer and the size of the buffer can be retrieved. This class also
42 * handles endian differences by serializing variables in network byte
43 * order (big endian).
44 */
45 class Packet
46 {
47 public:
48
49 /**
50 * Packet flags.
51 */
52 enum Flags
53 {
54 PEEK = 0x01 /// Do not actually remove anything.
55 };
56
57
58 /**
59 * Construct a packet with an initial capacity.
60 * \param capacity Initial capacity of the packet.
61 */
62 Packet(size_t capacity = PAGE_SIZE);
63
64 /**
65 * Construct a packet with some bytes from a buffer. The bytes will be
66 * copied into the packet, so you don't need to keep the original
67 * buffer.
68 * \param data The bytes.
69 * \param size The number of bytes.
70 */
71 Packet(const char* data, size_t size);
72
73
74 /**
75 * Insert a variable into the packet, serializing it. This usually
76 * increases the size of the packet by the size of the data type.
77 * \param value The value to insert.
78 * \return This.
79 */
80 bool put(bool value);
81 bool put(int8_t value);
82 bool put(int16_t value);
83 bool put(int32_t value);
84 bool put(int64_t value);
85 bool put(uint8_t value);
86 bool put(uint16_t value);
87 bool put(uint32_t value);
88 bool put(uint64_t value);
89 bool put(float value);
90 bool put(double value);
91
92 bool put(const char* value)
93 {
94 uint16_t length = strlen(value);
95 if (put(length))
96 {
97 size_t numBytes = write(value, length);
98 return numBytes == length;
99 }
100 return false;
101 }
102
103 template <class T>
104 bool put(const std::basic_string<T>& value)
105 {
106 if (put(uint16_t(value.length())))
107 {
108 size_t byteLength = value.length() * sizeof(T);
109 size_t numBytes = write(value.data(), byteLength);
110 return numBytes == byteLength;
111 }
112 return false;
113 }
114
115 template <class T>
116 bool put(const std::vector<T>& value)
117 {
118 if (put(uint16_t(value.size())))
119 {
120 typename std::vector<T>::const_iterator it;
121 for (it = value.begin(); it != value.end(); ++it)
122 {
123 if (!put(*it)) return false;
124 }
125 return true;
126 }
127 return false;
128 }
129
130
131 /**
132 * Write some bytes to the packet.
133 * \param bytes The bytes.
134 * \param size The number of bytes.
135 * return The number of bytes actually written.
136 */
137 size_t write(const void* bytes, size_t size);
138
139
140 /**
141 * Extract a variable from the packet. This usually decreases the size
142 * of the packet by the size of the data type.
143 * \param value Reference to the variable to extract.
144 * \return This.
145 */
146 bool get(bool& value, int flags = 0);
147 bool get(int8_t& value, int flags = 0);
148 bool get(int16_t& value, int flags = 0);
149 bool get(int32_t& value, int flags = 0);
150 bool get(int64_t& value, int flags = 0);
151 bool get(uint8_t& value, int flags = 0);
152 bool get(uint16_t& value, int flags = 0);
153 bool get(uint32_t& value, int flags = 0);
154 bool get(uint64_t& value, int flags = 0);
155 bool get(float& value, int flags = 0);
156 bool get(double& value, int flags = 0);
157
158 template <class T>
159 bool get(std::basic_string<T>& value, int flags = 0)
160 {
161 uint16_t length = 0;
162 if (get(length, flags))
163 {
164 size_t byteLength = length * sizeof(T);
165 T str[length];
166 size_t numBytes = read(str, byteLength, flags);
167 value.assign(str, numBytes);
168 return numBytes == byteLength;
169 }
170 return false;
171 }
172
173 template <class T>
174 bool get(std::vector<T>& value, int flags = 0)
175 {
176 uint16_t size = 0;
177 if (get(size, flags))
178 {
179 value.clear();
180 for (uint16_t i = 0; i < size; ++i)
181 {
182 T item;
183 if (get(item, flags)) value.push_back(item);
184 else return false;
185 }
186 return true;
187 }
188 return false;
189 }
190
191 /**
192 * Read some bytes from the packet.
193 * \param bytes The buffer to hold the bytes read.
194 * \param size The size of the read buffer.
195 * \return The number of bytes actually read.
196 */
197 size_t read(void* bytes, size_t size, int flags = 0);
198
199
200 /**
201 * Clear the contents of the packet, setting the size of the packet to
202 * zero.
203 */
204 void clear();
205
206
207 /**
208 * Reset the read/write markers to their initial positions, putting the
209 * packet in the state it was at right after construction.
210 */
211 void reset();
212
213
214 /**
215 * Get a pointer to an internal structure holding the serialized bytes
216 * of the packet.
217 * return The pointer.
218 */
219 const char* bytes() const
220 {
221 return mBuffer + mR;
222 }
223
224 /**
225 * Get the size of the buffer holding the serialized bytes of the
226 * packet.
227 * \return The number of bytes.
228 */
229 size_t size() const
230 {
231 return mW - mR;
232 }
233
234 // The rest of this stuff is just to implement correct copy semantics.
235
236 Packet(const Packet& copy);
237 Packet& operator=(const Packet& copy);
238 ~Packet();
239
240
241 private:
242
243 char* mBuffer;
244 size_t mSize;
245
246 size_t mR;
247 size_t mW;
248 size_t mOriginalW;
249
250 size_t mBoolR;
251 size_t mBoolW;
252 size_t mBoolNumR;
253 size_t mBoolNumW;
254 };
255
256
257 } // namespace Mf
258
259 #endif // _MOOF_PACKET_HH_
260
This page took 0.039661 seconds and 3 git commands to generate.