Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
storage.cpp
Go to the documentation of this file.
1/************************************************************************
2 ** This file is part of the network simulator Shawn. **
3 ** Copyright (C) 2004-2007 by the SwarmNet (www.swarmnet.de) project **
4 ** Shawn is free software; you can redistribute it and/or modify it **
5 ** under the terms of the BSD License. Refer to the shawn-licence.txt **
6 ** file in the root of the Shawn source tree for further details. **
7 ************************************************************************
8 ** **
9 ** \author Axel Wegener <wegener@itm.uni-luebeck.de> **
10 ** \author Bjoern Hendriks <hendriks@ibr.cs.tu-bs.de> **
11 ** **
12 ************************************************************************/
13
14#include "storage.h"
15
16#ifdef BUILD_TCPIP
17
18#include <iostream>
19#include <iterator>
20#include <sstream>
21#include <cassert>
22#include <algorithm>
23#include <iomanip>
24
25
26//#define NULLITER static_cast<list<unsigned char>::iterator>(0)
27
28namespace tcpip
29{
30
31 // ----------------------------------------------------------------------
33 {
34 init();
35 }
36
37
38 // ----------------------------------------------------------------------
39 Storage::Storage(const unsigned char packet[], int length)
40 {
41 assert(length >= 0); // fixed MB, 2015-04-21
42
43 store.reserve(length);
44 // Get the content
45 for(int i = 0; i < length; ++i) store.push_back(packet[i]);
46
47 init();
48 }
49
50
51 // ----------------------------------------------------------------------
53 {
54 // Initialize local variables
55 iter_ = store.begin();
56
57 short a = 0x0102;
58 unsigned char *p_a = reinterpret_cast<unsigned char*>(&a);
59 bigEndian_ = (p_a[0] == 0x01); // big endian?
60 }
61
62
63 // ----------------------------------------------------------------------
66
67
68 // ----------------------------------------------------------------------
70 {
71 return (iter_ != store.end()); // this implies !store.empty()
72 }
73
74
75 // ----------------------------------------------------------------------
76 unsigned int Storage::position() const
77 {
78 // According to C++ standard std::distance will simply compute the iterators
79 // difference for random access iterators as std::vector provides.
80 return static_cast<unsigned int>(std::distance(store.begin(), iter_));
81 }
82
83
84 // ----------------------------------------------------------------------
86 store.clear();
87 iter_ = store.begin();
88 }
89
90
91 // ----------------------------------------------------------------------
93 iter_ = store.begin();
94 }
95
96
97 // ----------------------------------------------------------------------
102 unsigned char Storage::readChar()
103 {
104 if ( !valid_pos() )
105 {
106 throw std::invalid_argument("Storage::readChar(): invalid position");
107 }
108 return readCharUnsafe();
109 }
110
111
112 // ----------------------------------------------------------------------
116 void Storage::writeChar(unsigned char value)
117 {
118 store.push_back(value);
119 iter_ = store.begin();
120 }
121
122
123 // ----------------------------------------------------------------------
129 {
130 int i = static_cast<int>(readChar());
131 if (i < 128) return i;
132 else return (i - 256);
133 }
134
135
136 // ----------------------------------------------------------------------
140 void Storage::writeByte(int value)
141 {
142 if (value < -128 || value > 127)
143 {
144 throw std::invalid_argument("Storage::writeByte(): Invalid value, not in [-128, 127]");
145 }
146 writeChar( static_cast<unsigned char>( (value+256) % 256 ) );
147 }
148
149
150 // ----------------------------------------------------------------------
156 {
157 return static_cast<int>(readChar());
158 }
159
160
161 // ----------------------------------------------------------------------
166 {
167 if (value < 0 || value > 255)
168 {
169 throw std::invalid_argument("Storage::writeUnsignedByte(): Invalid value, not in [0, 255]");
170 }
171 writeChar( static_cast<unsigned char>( value ));
172 }
173
174
175 // -----------------------------------------------------------------------
181 {
182 int len = readInt();
183 checkReadSafe(len);
184 StorageType::const_iterator end = iter_;
185 std::advance(end, len);
186 const std::string tmp(iter_, end);
187 iter_ = end;
188 return tmp;
189 }
190
191
192 // ----------------------------------------------------------------------
197 void Storage::writeString(const std::string &s)
198 {
199 writeInt(static_cast<int>(s.length()));
200
201 store.insert(store.end(), s.begin(), s.end());
202 iter_ = store.begin();
203 }
204
205
206 // -----------------------------------------------------------------------
211 std::vector<std::string> Storage::readStringList()
212 {
213 std::vector<std::string> tmp;
214 const int len = readInt();
215 tmp.reserve(len);
216 for (int i = 0; i < len; i++)
217 {
218 tmp.push_back(readString());
219 }
220 return tmp;
221 }
222
223
224 // -----------------------------------------------------------------------
229 std::vector<double> Storage::readDoubleList()
230 {
231 std::vector<double> tmp;
232 const int len = readInt();
233 tmp.reserve(len);
234 for (int i = 0; i < len; i++)
235 {
236 tmp.push_back(readDouble());
237 }
238 return tmp;
239 }
240
241
242 // ----------------------------------------------------------------------
247 void Storage::writeStringList(const std::vector<std::string> &s)
248 {
249 writeInt(static_cast<int>(s.size()));
250 for (std::vector<std::string>::const_iterator it = s.begin(); it!=s.end() ; it++)
251 {
252 writeString(*it);
253 }
254 }
255
256
257 // ----------------------------------------------------------------------
262 void Storage::writeDoubleList(const std::vector<double> &s)
263 {
264 writeInt(static_cast<int>(s.size()));
265 for (std::vector<double>::const_iterator it = s.begin(); it!=s.end() ; it++)
266 {
267 writeDouble(*it);
268 }
269 }
270
271
272 // ----------------------------------------------------------------------
281 {
282 short value = 0;
283 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
284 readByEndianess(p_value, 2);
285 return value;
286 }
287
288
289 // ----------------------------------------------------------------------
290 void Storage::writeShort( int value )
291 {
292 if (value < -32768 || value > 32767)
293 {
294 throw std::invalid_argument("Storage::writeShort(): Invalid value, not in [-32768, 32767]");
295 }
296
297 short svalue = static_cast<short>(value);
298 unsigned char *p_svalue = reinterpret_cast<unsigned char*>(&svalue);
299 writeByEndianess(p_svalue, 2);
300 }
301
302
303 // ----------------------------------------------------------------------
312 {
313 int value = 0;
314 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
315 readByEndianess(p_value, 4);
316 return value;
317 }
318
319
320 // ----------------------------------------------------------------------
321 void Storage::writeInt( int value )
322 {
323 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
324 writeByEndianess(p_value, 4);
325 }
326
327
328 // ----------------------------------------------------------------------
337 {
338 float value = 0;
339 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
340 readByEndianess(p_value, 4);
341 return value;
342 }
343
344
345 // ----------------------------------------------------------------------
346 void Storage::writeFloat( float value )
347 {
348 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
349 writeByEndianess(p_value, 4);
350 }
351
352
353 // ----------------------------------------------------------------------
354 void Storage::writeDouble( double value )
355 {
356 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
357 writeByEndianess(p_value, 8);
358 }
359
360
361 // ----------------------------------------------------------------------
363 {
364 double value = 0;
365 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
366 readByEndianess(p_value, 8);
367 return value;
368 }
369
370
371 // ----------------------------------------------------------------------
372 void Storage::writePacket(unsigned char* packet, int length)
373 {
374 store.insert(store.end(), &(packet[0]), &(packet[length]));
375 iter_ = store.begin(); // reserve() invalidates iterators
376 }
377
378
379 // ----------------------------------------------------------------------
380 void Storage::writePacket(const std::vector<unsigned char> &packet)
381 {
382 std::copy(packet.begin(), packet.end(), std::back_inserter(store));
383 iter_ = store.begin();
384 }
385
386
387 // ----------------------------------------------------------------------
389 {
390 // the compiler cannot deduce to use a const_iterator as source
391 store.insert<StorageType::const_iterator>(store.end(), other.iter_, other.store.end());
392 iter_ = store.begin();
393 }
394
395
396 // ----------------------------------------------------------------------
397 void Storage::checkReadSafe(unsigned int num) const
398 {
399 if (std::distance(iter_, store.end()) < static_cast<int>(num))
400 {
401 std::ostringstream msg;
402 msg << "tcpip::Storage::readIsSafe: want to read " << num << " bytes from Storage, "
403 << "but only " << std::distance(iter_, store.end()) << " remaining";
404 throw std::invalid_argument(msg.str());
405 }
406 }
407
408
409 // ----------------------------------------------------------------------
411 {
412 const unsigned char hb = *iter_;
413 ++iter_;
414 return hb;
415 }
416
417
418 // ----------------------------------------------------------------------
419 void Storage::writeByEndianess(const unsigned char * begin, unsigned int size)
420 {
421 const unsigned char * end = &(begin[size]);
422 if (bigEndian_)
423 store.insert(store.end(), begin, end);
424 else
425 store.insert(store.end(), std::reverse_iterator<const unsigned char *>(end), std::reverse_iterator<const unsigned char *>(begin));
426 iter_ = store.begin();
427 }
428
429
430 // ----------------------------------------------------------------------
431 void Storage::readByEndianess(unsigned char * array, int size)
432 {
434 if (bigEndian_)
435 {
436 for (int i = 0; i < size; ++i)
437 array[i] = readCharUnsafe();
438 }
439 else
440 {
441 for (int i = size - 1; i >= 0; --i)
442 array[i] = readCharUnsafe();
443 }
444 }
445
446
447 // ----------------------------------------------------------------------
448 std::string Storage::hexDump() const
449 {
450 std::ostringstream dump;
451 for(StorageType::const_iterator it = store.begin(); it != store.end(); ++it)
452 {
453 // insert spaces between values
454 if (it != store.begin())
455 dump << " ";
456 dump << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(*it);
457 }
458
459 return dump.str();
460 }
461
462}
463
464#endif // BUILD_TCPIP
465
466/*-----------------------------------------------------------------------
467 * Source $Source: $
468 * Version $Revision: 620 $
469 * Date $Date: 2011-07-08 17:39:10 +0200 (Fri, 08 Jul 2011) $
470 *-----------------------------------------------------------------------
471 * $Log: $
472 *-----------------------------------------------------------------------*/
virtual void writePacket(unsigned char *packet, int length)
Definition storage.cpp:372
bool bigEndian_
Definition storage.h:48
StorageType::const_iterator begin() const
Definition storage.h:121
virtual void writeFloat(float)
Definition storage.cpp:346
virtual int readShort()
Definition storage.cpp:280
virtual unsigned char readChar()
Definition storage.cpp:102
virtual std::string readString()
Definition storage.cpp:180
virtual void writeString(const std::string &s)
Definition storage.cpp:197
virtual float readFloat()
Definition storage.cpp:336
virtual unsigned int position() const
Definition storage.cpp:76
virtual void writeInt(int)
Definition storage.cpp:321
void resetPos()
Definition storage.cpp:92
StorageType::const_iterator end() const
Definition storage.h:122
virtual void writeDouble(double)
Definition storage.cpp:354
StorageType store
Definition storage.h:44
virtual int readUnsignedByte()
Definition storage.cpp:155
virtual void writeStringList(const std::vector< std::string > &s)
Definition storage.cpp:247
virtual void writeChar(unsigned char)
Definition storage.cpp:116
StorageType::const_iterator iter_
Definition storage.h:45
virtual void writeUnsignedByte(int)
Definition storage.cpp:165
StorageType::size_type size() const
Definition storage.h:119
virtual ~Storage()
Definition storage.cpp:64
virtual bool valid_pos()
Definition storage.cpp:69
virtual void writeDoubleList(const std::vector< double > &s)
Definition storage.cpp:262
unsigned char readCharUnsafe()
Read a byte without validity check.
Definition storage.cpp:410
std::string hexDump() const
Dump storage content as series of hex values.
Definition storage.cpp:448
void writeByEndianess(const unsigned char *begin, unsigned int size)
Write size elements of array begin according to endianess.
Definition storage.cpp:419
Storage()
Standard Constructor.
Definition storage.cpp:32
virtual void writeByte(int)
Definition storage.cpp:140
virtual void writeStorage(tcpip::Storage &store)
Definition storage.cpp:388
virtual int readByte()
Definition storage.cpp:128
void readByEndianess(unsigned char *array, int size)
Read size elements into array according to endianess.
Definition storage.cpp:431
virtual std::vector< std::string > readStringList()
Definition storage.cpp:211
virtual void writeShort(int)
Definition storage.cpp:290
void checkReadSafe(unsigned int num) const
Check if the next num bytes can be read safely.
Definition storage.cpp:397
void init()
Used in constructors to initialize local variables.
Definition storage.cpp:52
virtual double readDouble()
Definition storage.cpp:362
virtual int readInt()
Definition storage.cpp:311
virtual std::vector< double > readDoubleList()
Definition storage.cpp:229