bugfix: writing packets missing some bytes
[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 nPages = 1 + size / PAGE_SIZE;
220 int newSize = mSize + nPages * PAGE_SIZE;
221 char* newBuffer = (char*)realloc(mBuffer, newSize);
222 if (newBuffer)
223 {
224 mBuffer = newBuffer;
225 mSize = newSize;
226 nBytes = size;
227 }
228 if (!mBuffer) return 0;
229 }
230 memcpy(&mBuffer[mW], bytes, nBytes);
231 mW += nBytes;
232 return nBytes;
233 }
234
235
236 Packet& Packet::operator>>(bool& value)
237 {
238 int bit = mBoolNumR % 8;
239 if (bit == 0)
240 {
241 mBoolR = mR;
242
243 unsigned char byte = 0;
244 if (read(&byte, 1) == 0) return *this;
245 }
246
247 value = 1 & (mBuffer[mBoolR] >> bit);
248 ++mBoolNumR;
249
250 return *this;
251 }
252
253 Packet& Packet::operator>>(int8_t& value)
254 {
255 return *this >> (uint8_t&)value;
256 }
257
258 Packet& Packet::operator>>(int16_t& value)
259 {
260 return *this >> (uint16_t&)value;
261 }
262
263 Packet& Packet::operator>>(int32_t& value)
264 {
265 return *this >> (uint32_t&)value;
266 }
267
268 Packet& Packet::operator>>(int64_t& value)
269 {
270 return *this >> (uint64_t&)value;
271 }
272
273 Packet& Packet::operator>>(uint8_t& value)
274 {
275 read(&value, sizeof(value));
276 return *this;
277 }
278
279 Packet& Packet::operator>>(uint16_t& value)
280 {
281 read(&value, sizeof(value));
282 value = ntohs(value);
283 return *this;
284 }
285
286 Packet& Packet::operator>>(uint32_t& value)
287 {
288 read(&value, sizeof(value));
289 value = ntohl(value);
290 return *this;
291 }
292
293 Packet& Packet::operator>>(uint64_t& value)
294 {
295 read(&value, sizeof(value));
296 value = ntohll(value);
297 return *this;
298 }
299
300 Packet& Packet::operator>>(float& value)
301 {
302 // XXX: assumes the ieee-754
303 uint32_t* integer = reinterpret_cast<uint32_t*>(&value);
304 read(integer, sizeof(value));
305 *integer = htonl(*integer);
306 return *this;
307 }
308
309 Packet& Packet::operator>>(double& value)
310 {
311 // XXX: assumes the ieee-754
312 uint64_t* integer = reinterpret_cast<uint64_t*>(&value);
313 read(integer, sizeof(value));
314 *integer = htonll(*integer);
315 return *this;
316 }
317
318 size_t Packet::read(void* bytes, size_t size)
319 {
320 size_t nBytes = std::min(size, mW - mR);
321 memcpy(bytes, &mBuffer[mR], nBytes);
322 mR += nBytes;
323 return nBytes;
324 }
325
326
327 } // namespace Mf
328
This page took 0.043093 seconds and 4 git commands to generate.