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 |
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 |