]> Dogcows Code - chaz/yoink/blob - src/Moof/Packet.cc
8862f29bc9ba918ef23fb4608d539681fbb4f90a
[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 }
109
110 Packet::Packet(const char* data, size_t size) :
111 mBuffer((char*)malloc(size)),
112 mSize(size),
113 mR(0),
114 mW(size),
115 mBoolR(0),
116 mBoolW(0),
117 mBoolNumR(0),
118 mBoolNumW(0)
119 {
120 memcpy(mBuffer, data, size);
121 }
122
123
124 Packet::~Packet()
125 {
126 free(mBuffer);
127 }
128
129
130 Packet& Packet::operator<<(bool value)
131 {
132 int bit = mBoolNumW % 8;
133 if (bit == 0)
134 {
135 mBoolW = mW;
136
137 unsigned char byte = 0;
138 if (write(&byte, 1) == 0) return *this;
139 }
140
141 if (value) mBuffer[mBoolW] |= (1 << bit);
142 ++mBoolNumW;
143
144 return *this;
145 }
146
147
148 Packet& Packet::operator<<(int8_t value)
149 {
150 return *this << (uint8_t)value;
151 }
152
153 Packet& Packet::operator<<(int16_t value)
154 {
155 return *this << (uint16_t)value;
156 }
157
158 Packet& Packet::operator<<(int32_t value)
159 {
160 return *this << (uint32_t)value;
161 }
162
163 Packet& Packet::operator<<(int64_t value)
164 {
165 return *this << (uint64_t)value;
166 }
167
168
169 Packet& Packet::operator<<(uint8_t value)
170 {
171 write(&value, sizeof(value));
172 return *this;
173 }
174
175 Packet& Packet::operator<<(uint16_t value)
176 {
177 value = htons(value);
178 write(&value, sizeof(value));
179 return *this;
180 }
181
182 Packet& Packet::operator<<(uint32_t value)
183 {
184 value = htonl(value);
185 write(&value, sizeof(value));
186 return *this;
187 }
188
189 Packet& Packet::operator<<(uint64_t value)
190 {
191 value = htonll(value);
192 write(&value, sizeof(value));
193 return *this;
194 }
195
196 Packet& Packet::operator<<(float value)
197 {
198 // XXX: assumes the ieee-754
199 uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
200 *integer = htonl(*integer);
201 write(integer, sizeof(value));
202 return *this;
203 }
204
205 Packet& Packet::operator<<(double value)
206 {
207 // XXX: assumes the ieee-754
208 uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
209 *integer = htonll(*integer);
210 write(integer, sizeof(value));
211 return *this;
212 }
213
214 size_t Packet::write(const void* bytes, size_t size)
215 {
216 size_t nBytes = std::min(size, mSize - mW);
217 if (!mBuffer || nBytes < size)
218 {
219 int numPages = 1 + size / PAGE_SIZE;
220 int newSize = mSize + numPages * PAGE_SIZE;
221 char* newBuffer = (char*)realloc(mBuffer, newSize);
222 if (newBuffer)
223 {
224 mBuffer = newBuffer;
225 mSize = newSize;
226 }
227 }
228 memcpy(&mBuffer[mW], bytes, nBytes);
229 mW += nBytes;
230 return nBytes;
231 }
232
233
234 Packet& Packet::operator>>(bool& value)
235 {
236 int bit = mBoolNumR % 8;
237 if (bit == 0)
238 {
239 mBoolR = mR;
240
241 unsigned char byte = 0;
242 if (read(&byte, 1) == 0) return *this;
243 }
244
245 value = 1 & (mBuffer[mBoolR] >> bit);
246 ++mBoolNumR;
247
248 return *this;
249 }
250
251 Packet& Packet::operator>>(int8_t& value)
252 {
253 return *this >> (uint8_t&)value;
254 }
255
256 Packet& Packet::operator>>(int16_t& value)
257 {
258 return *this >> (uint16_t&)value;
259 }
260
261 Packet& Packet::operator>>(int32_t& value)
262 {
263 return *this >> (uint32_t&)value;
264 }
265
266 Packet& Packet::operator>>(int64_t& value)
267 {
268 return *this >> (uint64_t&)value;
269 }
270
271 Packet& Packet::operator>>(uint8_t& value)
272 {
273 read(&value, sizeof(value));
274 return *this;
275 }
276
277 Packet& Packet::operator>>(uint16_t& value)
278 {
279 read(&value, sizeof(value));
280 value = ntohs(value);
281 return *this;
282 }
283
284 Packet& Packet::operator>>(uint32_t& value)
285 {
286 read(&value, sizeof(value));
287 value = ntohl(value);
288 return *this;
289 }
290
291 Packet& Packet::operator>>(uint64_t& value)
292 {
293 read(&value, sizeof(value));
294 value = ntohll(value);
295 return *this;
296 }
297
298 Packet& Packet::operator>>(float& value)
299 {
300 // XXX: assumes the ieee-754
301 uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
302 read(integer, sizeof(value));
303 *integer = htonl(*integer);
304 return *this;
305 }
306
307 Packet& Packet::operator>>(double& value)
308 {
309 // XXX: assumes the ieee-754
310 uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
311 read(integer, sizeof(value));
312 *integer = htonll(*integer);
313 return *this;
314 }
315
316 size_t Packet::read(void* bytes, size_t size)
317 {
318 size_t nBytes = std::min(size, mW - mR);
319 memcpy(bytes, &mBuffer[mR], nBytes);
320 mR += nBytes;
321 return nBytes;
322 }
323
324
325 } // namespace Mf
326
This page took 0.047193 seconds and 3 git commands to generate.