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