2bbceb54f89996e5ff5e293921b440c88b5154db
[chaz/yoink] / src / Moof / old / 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 capacity) :
99 mBuffer((char*)malloc(capacity)),
100 mSize(capacity),
101 mR(0),
102 mW(0),
103 mOriginalW(0),
104 mBoolR(0),
105 mBoolW(0),
106 mBoolNumR(0),
107 mBoolNumW(0) {}
108
109 Packet::Packet(const char* data, size_t size) :
110 mBuffer((char*)malloc(size)),
111 mSize(size),
112 mR(0),
113 mW(size),
114 mOriginalW(size),
115 mBoolR(0),
116 mBoolW(0),
117 mBoolNumR(0),
118 mBoolNumW(0)
119 {
120 if (mBuffer) memcpy(mBuffer, data, size);
121 }
122
123
124 Packet::Packet(const Packet& copy) :
125 mBuffer((char*)malloc(copy.mSize)),
126 mSize(copy.mSize),
127 mR(copy.mR),
128 mW(copy.mW),
129 mOriginalW(copy.mOriginalW),
130 mBoolR(copy.mBoolR),
131 mBoolW(copy.mBoolW),
132 mBoolNumR(copy.mBoolNumR),
133 mBoolNumW(copy.mBoolNumW)
134 {
135 if (mBuffer) memcpy(mBuffer, copy.mBuffer, mSize);
136 }
137
138 Packet& Packet::operator=(const Packet& copy)
139 {
140 free(mBuffer);
141
142 mBuffer = (char*)malloc(copy.mSize);
143 mSize = copy.mSize;
144 mR = copy.mR;
145 mW = copy.mW;
146 mOriginalW = copy.mOriginalW;
147 mBoolR = copy.mBoolR;
148 mBoolW = copy.mBoolW;
149 mBoolNumR = copy.mBoolNumR;
150 mBoolNumW = copy.mBoolNumW;
151 if (mBuffer) memcpy(mBuffer, copy.mBuffer, mSize);
152 return *this;
153 }
154
155
156 Packet::~Packet()
157 {
158 free(mBuffer);
159 }
160
161
162 bool Packet::put(bool value)
163 {
164 int bit = mBoolNumW % 8;
165 if (bit == 0)
166 {
167 mBoolW = mW;
168
169 unsigned char byte = 0;
170 if (write(&byte, 1) == 0) return false;
171 }
172
173 if (value) mBuffer[mBoolW] |= (1 << bit);
174 ++mBoolNumW;
175 return true;
176 }
177
178
179 bool Packet::put(int8_t value)
180 {
181 return put(uint8_t(value));
182 }
183
184 bool Packet::put(int16_t value)
185 {
186 return put(uint16_t(value));
187 }
188
189 bool Packet::put(int32_t value)
190 {
191 return put(uint32_t(value));
192 }
193
194 bool Packet::put(int64_t value)
195 {
196 return put(uint64_t(value));
197 }
198
199
200 bool Packet::put(uint8_t value)
201 {
202 return write(&value, sizeof(value)) == sizeof(value);
203 }
204
205 bool Packet::put(uint16_t value)
206 {
207 value = htons(value);
208 return write(&value, sizeof(value)) == sizeof(value);
209 }
210
211 bool Packet::put(uint32_t value)
212 {
213 value = htonl(value);
214 return write(&value, sizeof(value)) == sizeof(value);
215 }
216
217 bool Packet::put(uint64_t value)
218 {
219 value = htonll(value);
220 return write(&value, sizeof(value)) == sizeof(value);
221 }
222
223 bool Packet::put(float value)
224 {
225 // XXX: assumes the ieee-754
226 uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
227 *integer = htonl(*integer);
228 return write(integer, sizeof(value)) == sizeof(value);
229 }
230
231 bool Packet::put(double value)
232 {
233 // XXX: assumes the ieee-754
234 uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
235 *integer = htonll(*integer);
236 return write(integer, sizeof(value)) == sizeof(value);
237 }
238
239
240 size_t Packet::write(const void* bytes, size_t size)
241 {
242 size_t nBytes = std::min(size, mSize - mW);
243 if (!mBuffer || nBytes < size)
244 {
245 int nPages = 1 + size / PAGE_SIZE;
246 int newSize = mSize + nPages * PAGE_SIZE;
247 char* newBuffer = (char*)realloc(mBuffer, newSize);
248 if (newBuffer)
249 {
250 mBuffer = newBuffer;
251 mSize = newSize;
252 nBytes = size;
253 }
254 if (!mBuffer) return 0;
255 }
256 memcpy(mBuffer + mW, bytes, nBytes);
257 mW += nBytes;
258 return nBytes;
259 }
260
261
262 bool Packet::get(bool& value, int flags)
263 {
264 int bit = mBoolNumR % 8;
265 if (bit == 0)
266 {
267 mBoolR = mR;
268
269 unsigned char byte = 0;
270 if (read(&byte, 1, flags) == 0) return false;
271 }
272
273 value = 1 & (mBuffer[mBoolR] >> bit);
274 if (!(flags & PEEK)) ++mBoolNumR;
275 return true;
276 }
277
278 bool Packet::get(int8_t& value, int flags)
279 {
280 return get((uint8_t&)value, flags);
281 }
282
283 bool Packet::get(int16_t& value, int flags)
284 {
285 return get((uint16_t&)value, flags);
286 }
287
288 bool Packet::get(int32_t& value, int flags)
289 {
290 return get((uint32_t&)value, flags);
291 }
292
293 bool Packet::get(int64_t& value, int flags)
294 {
295 return get((uint64_t&)value, flags);
296 }
297
298 bool Packet::get(uint8_t& value, int flags)
299 {
300 size_t numBytes = read(&value, sizeof(value), flags);
301 return numBytes == sizeof(value);
302 }
303
304 bool Packet::get(uint16_t& value, int flags)
305 {
306 size_t numBytes = read(&value, sizeof(value), flags);
307 value = ntohs(value);
308 return numBytes == sizeof(value);
309 }
310
311 bool Packet::get(uint32_t& value, int flags)
312 {
313 size_t numBytes = read(&value, sizeof(value), flags);
314 value = ntohl(value);
315 return numBytes == sizeof(value);
316 }
317
318 bool Packet::get(uint64_t& value, int flags)
319 {
320 size_t numBytes = read(&value, sizeof(value), flags);
321 value = ntohll(value);
322 return numBytes == sizeof(value);
323 }
324
325 bool Packet::get(float& value, int flags)
326 {
327 // XXX: assumes the ieee-754
328 uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
329 size_t numBytes = read(integer, sizeof(value));
330 *integer = htonl(*integer);
331 return numBytes == sizeof(value);
332 }
333
334 bool Packet::get(double& value, int flags)
335 {
336 // XXX: assumes the ieee-754
337 uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
338 size_t numBytes = read(integer, sizeof(value));
339 *integer = htonll(*integer);
340 return numBytes == sizeof(value);
341 }
342
343
344 size_t Packet::read(void* bytes, size_t size, int flags)
345 {
346 size_t nBytes = std::min(size, mW - mR);
347 memcpy(bytes, mBuffer + mR, nBytes);
348 if (!(flags & PEEK)) mR += nBytes;
349 return nBytes;
350 }
351
352
353 void Packet::clear()
354 {
355 mR = 0;
356 mW = 0;
357 mBoolR = 0;
358 mBoolW = 0;
359 mBoolNumR = 0;
360 mBoolNumW = 0;
361 }
362
363
364 void Packet::reset()
365 {
366 mR = 0;
367 mW = mOriginalW;
368 mBoolR = 0;
369 mBoolW = 0;
370 mBoolNumR = 0;
371 mBoolNumW = 0;
372 }
373
374
375 } // namespace Mf
376
This page took 0.042913 seconds and 3 git commands to generate.