sources/network/bytestream.cpp

branch
protocol5
changeset 106
7b156b764d11
parent 99
f9f73eeba3b7
child 109
e4966d7e615d
equal deleted inserted replaced
104:a76af67a3a4b 106:7b156b764d11
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "bytestream.h" 31 #include "bytestream.h"
32 #include <string.h> 32 #include <string.h>
33 BEGIN_ZFC_NAMESPACE
33 34
34 // ------------------------------------------------------------------------------------------------- 35 // -------------------------------------------------------------------------------------------------
35 // 36 //
36 Bytestream::Bytestream (unsigned long length) : 37 Bytestream::Bytestream (unsigned long length) :
37 m_data (nullptr) 38 m_data (nullptr)
70 { 71 {
71 delete[] m_data; 72 delete[] m_data;
72 } 73 }
73 74
74 // ------------------------------------------------------------------------------------------------- 75 // -------------------------------------------------------------------------------------------------
75 METHOD 76 Bytestream& Bytestream::operator= (const Bytestream& other)
76 Bytestream::operator= (const Bytestream& other) -> Bytestream&
77 { 77 {
78 init (other.data(), other.written_length()); 78 init (other.data(), other.written_length());
79 return *this; 79 return *this;
80 } 80 }
81 81
82 // ------------------------------------------------------------------------------------------------- 82 // -------------------------------------------------------------------------------------------------
83 // 83 //
84 METHOD 84 void Bytestream::resize (unsigned long newsize)
85 Bytestream::resize (unsigned long newsize) -> void
86 { 85 {
87 Vector<unsigned char> olddata; 86 Vector<unsigned char> olddata;
88 unsigned long oldsize = 0L; 87 unsigned long oldsize = 0L;
89 88
90 if (m_data != nullptr) 89 if (m_data != nullptr)
96 95
97 delete[] m_data; 96 delete[] m_data;
98 m_allocatedSize = newsize; 97 m_allocatedSize = newsize;
99 m_data = new unsigned char[newsize]; 98 m_data = new unsigned char[newsize];
100 99
101 if (olddata > 0L) 100 if (oldsize > 0L)
102 memcpy (m_data, olddata, min (oldsize, newsize)); 101 memcpy (m_data, olddata, min (oldsize, newsize));
103 } 102 }
104 103
105 // ------------------------------------------------------------------------------------------------- 104 // -------------------------------------------------------------------------------------------------
106 // 105 //
107 METHOD 106 void Bytestream::init (const unsigned char* data, unsigned long length)
108 Bytestream::init (const unsigned char* data, unsigned long length) -> void
109 { 107 {
110 resize (length); 108 resize (length);
111 memcpy (m_data, data, length); 109 memcpy (m_data, data, length);
112 m_cursor = &m_data[0]; 110 m_cursor = &m_data[0];
113 m_writtenLength = length; 111 m_writtenLength = length;
114 } 112 }
115 113
116 // ------------------------------------------------------------------------------------------------- 114 // -------------------------------------------------------------------------------------------------
117 // 115 //
118 METHOD 116 void Bytestream::clear()
119 Bytestream::clear() -> void
120 { 117 {
121 m_cursor = &m_data[0]; 118 m_cursor = &m_data[0];
122 m_writtenLength = 0; 119 m_writtenLength = 0;
123 } 120 }
124 121
125 // ------------------------------------------------------------------------------------------------- 122 // -------------------------------------------------------------------------------------------------
126 // 123 //
127 METHOD 124 void Bytestream::ensure_read_space (unsigned int bytes)
128 Bytestream::ensure_read_space (unsigned int bytes) -> void
129 { 125 {
130 if (bytes_left() < bytes) 126 if (bytes_left() < bytes)
131 { 127 {
132 int bytesPast = bytes - bytes_left(); 128 int bytesPast = bytes - bytes_left();
133 129
138 } 134 }
139 } 135 }
140 136
141 // ------------------------------------------------------------------------------------------------- 137 // -------------------------------------------------------------------------------------------------
142 // 138 //
143 METHOD 139 int8_t Bytestream::read_byte()
144 Bytestream::read_byte() -> char
145 { 140 {
146 ensure_read_space (1); 141 ensure_read_space (1);
147 return *m_cursor++; 142 return *m_cursor++;
148 } 143 }
149 144
150 // ------------------------------------------------------------------------------------------------- 145 // -------------------------------------------------------------------------------------------------
151 // 146 //
152 METHOD 147 int16_t Bytestream::read_short()
153 Bytestream::read_short() -> short int
154 { 148 {
155 ensure_read_space (2); 149 ensure_read_space (2);
156 short int result = 0; 150 short int result = 0;
157 151
158 for (int i = 0; i < 2; ++i) 152 for (int i = 0; i < 2; ++i)
162 return result; 156 return result;
163 } 157 }
164 158
165 // ------------------------------------------------------------------------------------------------- 159 // -------------------------------------------------------------------------------------------------
166 // 160 //
167 METHOD 161 int32_t Bytestream::read_long()
168 Bytestream::read_long() -> long int
169 { 162 {
170 ensure_read_space (4); 163 ensure_read_space (4);
171 long int result = 0; 164 long int result = 0;
172 165
173 for (int i = 0; i < 4; ++i) 166 for (int i = 0; i < 4; ++i)
177 return result; 170 return result;
178 } 171 }
179 172
180 // ------------------------------------------------------------------------------------------------- 173 // -------------------------------------------------------------------------------------------------
181 // 174 //
182 METHOD 175 float Bytestream::read_float()
183 Bytestream::read_float() -> float
184 { 176 {
185 float value; 177 float value;
186 int intvalue = read_long(); 178 int intvalue = read_long();
187 memcpy (&value, &intvalue, sizeof intvalue); 179 memcpy (&value, &intvalue, sizeof intvalue);
188 return value; 180 return value;
189 } 181 }
190 182
191 // ------------------------------------------------------------------------------------------------- 183 // -------------------------------------------------------------------------------------------------
192 // 184 //
193 METHOD 185 String Bytestream::read_string()
194 Bytestream::read_string() -> String
195 { 186 {
196 // Zandronum sends strings of maximum 2048 characters, though it only 187 // Zandronum sends strings of maximum 2048 characters, though it only
197 // reads 2047-character long ones so I guess we can follow up and do 188 // reads 2047-character long ones so I guess we can follow up and do
198 // the same :-) 189 // the same :-)
199 static char buffer[MAX_NETWORK_STRING]; 190 static char buffer[MAX_NETWORK_STRING];
200 unsigned char* stringEnd; 191 unsigned char* stringEnd;
201 unsigned char* stringBegin = m_cursor; 192 unsigned char* stringBegin = m_cursor;
202 unsigned char* end = m_data + allocated_size(); 193 unsigned char* end = m_data + allocated_size();
203 194
204 // where's the end of the string? 195 // Where's the end of the string?
205 for (stringEnd = m_cursor; *stringEnd != '\0'; ++stringEnd) 196 for (stringEnd = m_cursor; *stringEnd != '\0'; ++stringEnd)
206 { 197 {
207 if (stringEnd == end) 198 if (stringEnd == end)
208 // past the end of the buffer! Argh! 199 {
209 throw IOError ("unterminated string in packet"); 200 // Past the end of the buffer
201 throw IOError ("unterminated or too long string in packet");
202 }
210 } 203 }
211 204
205 unsigned int length = stringEnd - m_cursor;
212 m_cursor = stringEnd + 1; 206 m_cursor = stringEnd + 1;
213 unsigned int length = stringEnd - m_cursor;
214
215 // ensure we won't write past the buffer (note: we still moved
216 // past the excess bytes in the above statement, those are ignored)
217 if (length >= MAX_NETWORK_STRING)
218 length = MAX_NETWORK_STRING - 1;
219
220 memcpy (buffer, stringBegin, length); 207 memcpy (buffer, stringBegin, length);
221 buffer[length] = '\0'; 208 buffer[length] = '\0';
222 return String (buffer); 209 return String (buffer);
223 } 210 }
224 211
225 // ------------------------------------------------------------------------------------------------- 212 // -------------------------------------------------------------------------------------------------
226 // 213 //
227 METHOD 214 void Bytestream::read (unsigned char* buffer, unsigned long length)
228 Bytestream::read (unsigned char* buffer, unsigned long length) -> void
229 { 215 {
230 ensure_read_space (length); 216 ensure_read_space (length);
231 memcpy (buffer, m_cursor, length); 217 memcpy (buffer, m_cursor, length);
232 m_cursor += length; 218 m_cursor += length;
233 } 219 }
234 220
235 // ------------------------------------------------------------------------------------------------- 221 // -------------------------------------------------------------------------------------------------
236 // 222 //
237 METHOD 223 void Bytestream::write (unsigned char val)
238 Bytestream::write (unsigned char val) -> void
239 { 224 {
240 *m_cursor++ = val; 225 *m_cursor++ = val;
241 m_writtenLength++; 226 m_writtenLength++;
242 } 227 }
243 228
244 // ------------------------------------------------------------------------------------------------- 229 // -------------------------------------------------------------------------------------------------
245 // 230 //
246 METHOD 231 void Bytestream::write (const unsigned char* val, unsigned int length)
247 Bytestream::write (const unsigned char* val, unsigned int length) -> void
248 { 232 {
249 grow_to_fit (length); 233 grow_to_fit (length);
250 memcpy (m_cursor, val, length); 234 memcpy (m_cursor, val, length);
251 m_cursor += length; 235 m_cursor += length;
252 m_writtenLength += length; 236 m_writtenLength += length;
253 } 237 }
254 238
255 // ------------------------------------------------------------------------------------------------- 239 // -------------------------------------------------------------------------------------------------
256 // 240 //
257 METHOD 241 void Bytestream::grow_to_fit (unsigned long bytes)
258 Bytestream::grow_to_fit (unsigned long bytes) -> void
259 { 242 {
260 if (space_left() < bytes) 243 if (space_left() < bytes)
261 resize (allocated_size() + bytes + 128); 244 resize (allocated_size() + bytes + 128);
262 } 245 }
263 246
264 // ------------------------------------------------------------------------------------------------- 247 // -------------------------------------------------------------------------------------------------
265 // 248 //
266 METHOD 249 void Bytestream::write_byte (int8_t val)
267 Bytestream::write_byte (char val) -> void
268 { 250 {
269 grow_to_fit (1); 251 grow_to_fit (1);
270 write (val); 252 write (val);
271 } 253 }
272 254
273 // ------------------------------------------------------------------------------------------------- 255 // -------------------------------------------------------------------------------------------------
274 // 256 //
275 METHOD 257 void Bytestream::write_short (int16_t val)
276 Bytestream::write_short (short int val) -> void
277 { 258 {
278 grow_to_fit (2); 259 grow_to_fit (2);
279 260
280 for (int i = 0; i < 2; ++i) 261 for (int i = 0; i < 2; ++i)
281 write ((val >> (i * 8)) & 0xFF); 262 write ((val >> (i * 8)) & 0xFF);
282 } 263 }
283 264
284 // ------------------------------------------------------------------------------------------------- 265 // -------------------------------------------------------------------------------------------------
285 // 266 //
286 METHOD 267 void Bytestream::write_long (int32_t val)
287 Bytestream::write_long (long int val) -> void
288 { 268 {
289 grow_to_fit (4); 269 grow_to_fit (4);
290 270
291 for (int i = 0; i < 4; ++i) 271 for (int i = 0; i < 4; ++i)
292 write ((val >> (i * 8)) & 0xFF); 272 write ((val >> (i * 8)) & 0xFF);
293 } 273 }
294 274
295 // ------------------------------------------------------------------------------------------------- 275 // -------------------------------------------------------------------------------------------------
296 // 276 //
297 METHOD 277 void Bytestream::write_float (float val)
298 Bytestream::write_float (float val) -> void
299 { 278 {
300 // I know this is probably dangerous but this is what Zandronum does so yeah 279 // I know this is probably dangerous but this is what Zandronum does so yeah
301 int intvalue; 280 int intvalue;
302 memcpy (&intvalue, &val, sizeof val); 281 memcpy (&intvalue, &val, sizeof val);
303 write_long (intvalue); 282 write_long (intvalue);
304 } 283 }
305 284
306 // ------------------------------------------------------------------------------------------------- 285 // -------------------------------------------------------------------------------------------------
307 // 286 //
308 METHOD 287 void Bytestream::write_string (const String& val)
309 Bytestream::write_string (const String& val) -> void
310 { 288 {
311 grow_to_fit (val.length() + 1); 289 grow_to_fit (val.length() + 1);
312 write (reinterpret_cast<const unsigned char*> (val.chars()), val.length()); 290 write (reinterpret_cast<const unsigned char*> (val.chars()), val.length());
313 write (0); 291 write (0);
314 } 292 }
315 293
316 // ------------------------------------------------------------------------------------------------- 294 // -------------------------------------------------------------------------------------------------
317 // 295 //
318 METHOD 296 void Bytestream::write_buffer (const Bytestream& other)
319 Bytestream::write_buffer (const Bytestream& other) -> void
320 { 297 {
321 write (other.data(), other.written_length()); 298 write (other.data(), other.written_length());
322 } 299 }
300
301 END_ZFC_NAMESPACE

mercurial