842d6c1d9e9406d89dcf488b61b5df6f8b0a8cb1
[chaz/yoink] / src / Moof / Packet.cc
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 #include "../config.h"
13
14 #include <algorithm>
15 #if HAVE_BYTESWAP_H
16 #include <byteswap.h>
17 #endif
18 #include <cstdlib>
19
20 #if HAVE_ARPA_INET_H
21 #include <arpa/inet.h>
22 #endif
23
24 #include <SDL/SDL.h>
25
26 #include "Packet.hh"
27
28
29 #ifndef bswap_16
30 #define bswap_16(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
31 #endif
32
33 #ifndef bswap_32
34 #define bswap_32(x) ((((x) & 0xff000000) >> 24) | \
35 (((x) & 0x00ff0000) >> 8) | \
36 (((x) & 0x0000ff00) << 8) | \
37 (((x) & 0x000000ff) << 24))
38 #endif
39
40 #ifndef bswap_64
41 #define bswap_64(x) (((x) << 56) | \
42 (((x) << 40) & 0xff000000000000ULL) | \
43 (((x) << 24) & 0xff0000000000ULL) | \
44 (((x) << 8) & 0xff00000000ULL) | \
45 (((x) >> 8) & 0xff000000ULL) | \
46 (((x) >> 24) & 0xff0000ULL) | \
47 (((x) >> 40) & 0xff00ULL) | \
48 ((x) >> 56))
49 #endif
50
51
52 #if !HAVE_ARPA_INET_H
53 static uint16_t htons(uint16_t x)
54 {
55 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
56 return bswap_16(x);
57 #else
58 return x;
59 #endif
60 }
61 static uint16_t ntohs(uint16_t x)
62 {
63 return htons(x);
64 }
65
66 static uint32_t htonl(uint32_t x)
67 {
68 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
69 return bswap_32(x);
70 #else
71 return x;
72 #endif
73 }
74 static uint32_t ntohl(uint32_t x)
75 {
76 return htonl(x);
77 }
78 #endif
79
80
81 static uint64_t htonll(uint64_t x)
82 {
83 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
84 return bswap_64(x);
85 #else
86 return x;
87 #endif
88 }
89 static uint64_t ntohll(uint64_t x)
90 {
91 return htonll(x);
92 }
93
94
95 namespace Mf {
96
97
98 Packet::Packet(size_t size) :
99 mBuffer((char*)malloc(size)),
100 mSize(size),
101 mR(0),
102 mW(0),
103 mBoolR(0),
104 mBoolW(0),
105 mBoolNumR(0),
106 mBoolNumW(0) {}
107
108 Packet::Packet(const char* data, size_t size) :
109 mBuffer((char*)malloc(size)),
110 mSize(size),
111 mR(0),
112 mW(size),
113 mBoolR(0),
114 mBoolW(0),
115 mBoolNumR(0),
116 mBoolNumW(0)
117 {
118 if (mBuffer) memcpy(mBuffer, data, size);
119 }
120
121
122 Packet::Packet(const Packet& copy) :
123 mBuffer((char*)malloc(copy.mSize)),
124 mSize(copy.mSize),
125 mR(copy.mR),
126 mW(copy.mW),
127 mBoolR(copy.mBoolR),
128 mBoolW(copy.mBoolW),
129 mBoolNumR(copy.mBoolNumR),
130 mBoolNumW(copy.mBoolNumW)
131 {
132 if (mBuffer) memcpy(mBuffer, copy.mBuffer, mSize);
133 }
134
135 Packet& Packet::operator=(const Packet& copy)
136 {
137 free(mBuffer);
138
139 mBuffer = (char*)malloc(copy.mSize);
140 mSize = copy.mSize;
141 mR = copy.mR;
142 mW = copy.mW;
143 mBoolR = copy.mBoolR;
144 mBoolW = copy.mBoolW;
145 mBoolNumR = copy.mBoolNumR;
146 mBoolNumW = copy.mBoolNumW;
147 if (mBuffer) memcpy(mBuffer, copy.mBuffer, mSize);
148 return *this;
149 }
150
151
152 Packet::~Packet()
153 {
154 free(mBuffer);
155 }
156
157
158 Packet& Packet::operator<<(bool value)
159 {
160 int bit = mBoolNumW % 8;
161 if (bit == 0)
162 {
163 mBoolW = mW;
164
165 unsigned char byte = 0;
166 if (write(&byte, 1) == 0) return *this;
167 }
168
169 if (value) mBuffer[mBoolW] |= (1 << bit);
170 ++mBoolNumW;
171
172 return *this;
173 }
174
175
176 Packet& Packet::operator<<(int8_t value)
177 {
178 return *this << (uint8_t)value;
179 }
180
181 Packet& Packet::operator<<(int16_t value)
182 {
183 return *this << (uint16_t)value;
184 }
185
186 Packet& Packet::operator<<(int32_t value)
187 {
188 return *this << (uint32_t)value;
189 }
190
191 Packet& Packet::operator<<(int64_t value)
192 {
193 return *this << (uint64_t)value;
194 }
195
196
197 Packet& Packet::operator<<(uint8_t value)
198 {
199 write(&value, sizeof(value));
200 return *this;
201 }
202
203 Packet& Packet::operator<<(uint16_t value)
204 {
205 value = htons(value);
206 write(&value, sizeof(value));
207 return *this;
208 }
209
210 Packet& Packet::operator<<(uint32_t value)
211 {
212 value = htonl(value);
213 write(&value, sizeof(value));
214 return *this;
215 }
216
217 Packet& Packet::operator<<(uint64_t value)
218 {
219 value = htonll(value);
220 write(&value, sizeof(value));
221 return *this;
222 }
223
224 Packet& Packet::operator<<(float value)
225 {
226 // XXX: assumes the ieee-754
227 uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
228 *integer = htonl(*integer);
229 write(integer, sizeof(value));
230 return *this;
231 }
232
233 Packet& Packet::operator<<(double value)
234 {
235 // XXX: assumes the ieee-754
236 uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
237 *integer = htonll(*integer);
238 write(integer, sizeof(value));
239 return *this;
240 }
241
242 size_t Packet::write(const void* bytes, size_t size)
243 {
244 size_t nBytes = std::min(size, mSize - mW);
245 if (!mBuffer || nBytes < size)
246 {
247 int nPages = 1 + size / PAGE_SIZE;
248 int newSize = mSize + nPages * PAGE_SIZE;
249 char* newBuffer = (char*)realloc(mBuffer, newSize);
250 if (newBuffer)
251 {
252 mBuffer = newBuffer;
253 mSize = newSize;
254 nBytes = size;
255 }
256 if (!mBuffer) return 0;
257 }
258 memcpy(mBuffer + mW, bytes, nBytes);
259 mW += nBytes;
260 return nBytes;
261 }
262
263
264 Packet& Packet::operator>>(bool& value)
265 {
266 int bit = mBoolNumR % 8;
267 if (bit == 0)
268 {
269 mBoolR = mR;
270
271 unsigned char byte = 0;
272 if (read(&byte, 1) == 0) return *this;
273 }
274
275 value = 1 & (mBuffer[mBoolR] >> bit);
276 ++mBoolNumR;
277
278 return *this;
279 }
280
281 Packet& Packet::operator>>(int8_t& value)
282 {
283 return *this >> (uint8_t&)value;
284 }
285
286 Packet& Packet::operator>>(int16_t& value)
287 {
288 return *this >> (uint16_t&)value;
289 }
290
291 Packet& Packet::operator>>(int32_t& value)
292 {
293 return *this >> (uint32_t&)value;
294 }
295
296 Packet& Packet::operator>>(int64_t& value)
297 {
298 return *this >> (uint64_t&)value;
299 }
300
301 Packet& Packet::operator>>(uint8_t& value)
302 {
303 read(&value, sizeof(value));
304 return *this;
305 }
306
307 Packet& Packet::operator>>(uint16_t& value)
308 {
309 read(&value, sizeof(value));
310 value = ntohs(value);
311 return *this;
312 }
313
314 Packet& Packet::operator>>(uint32_t& value)
315 {
316 read(&value, sizeof(value));
317 value = ntohl(value);
318 return *this;
319 }
320
321 Packet& Packet::operator>>(uint64_t& value)
322 {
323 read(&value, sizeof(value));
324 value = ntohll(value);
325 return *this;
326 }
327
328 Packet& Packet::operator>>(float& value)
329 {
330 // XXX: assumes the ieee-754
331 uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
332 read(integer, sizeof(value));
333 *integer = htonl(*integer);
334 return *this;
335 }
336
337 Packet& Packet::operator>>(double& value)
338 {
339 // XXX: assumes the ieee-754
340 uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
341 read(integer, sizeof(value));
342 *integer = htonll(*integer);
343 return *this;
344 }
345
346 size_t Packet::read(void* bytes, size_t size)
347 {
348 size_t nBytes = std::min(size, mW - mR);
349 memcpy(bytes, mBuffer + mR, nBytes);
350 mR += nBytes;
351 return nBytes;
352 }
353
354
355 void Packet::clear()
356 {
357 mR = 0;
358 mW = 0;
359 mBoolR = 0;
360 mBoolW = 0;
361 mBoolNumR = 0;
362 mBoolNumW = 0;
363 }
364
365
366 } // namespace Mf
367
This page took 0.046373 seconds and 3 git commands to generate.