Eclipse SUMO - Simulation of Urban MObility
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 
28 namespace 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  // ----------------------------------------------------------------------
65  {}
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  // ----------------------------------------------------------------------
85  void Storage::reset() {
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  // -----------------------------------------------------------------------
180  std::string Storage::readString()
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  // ----------------------------------------------------------------------
410  unsigned char Storage::readCharUnsafe()
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
void reset()
Definition: storage.cpp:85
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
Definition: socket.cpp:62