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  // ----------------------------------------------------------------------
52  void Storage::init()
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  // ----------------------------------------------------------------------
69  bool Storage::valid_pos()
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  {
87  store.clear();
88  iter_ = store.begin();
89  }
90 
91 
92  // ----------------------------------------------------------------------
97  unsigned char Storage::readChar()
98  {
99  if ( !valid_pos() )
100  {
101  throw std::invalid_argument("Storage::readChar(): invalid position");
102  }
103  return readCharUnsafe();
104  }
105 
106 
107  // ----------------------------------------------------------------------
111  void Storage::writeChar(unsigned char value)
112  {
113  store.push_back(value);
114  iter_ = store.begin();
115  }
116 
117 
118  // ----------------------------------------------------------------------
123  int Storage::readByte()
124  {
125  int i = static_cast<int>(readChar());
126  if (i < 128) return i;
127  else return (i - 256);
128  }
129 
130 
131  // ----------------------------------------------------------------------
135  void Storage::writeByte(int value)
136  {
137  if (value < -128 || value > 127)
138  {
139  throw std::invalid_argument("Storage::writeByte(): Invalid value, not in [-128, 127]");
140  }
141  writeChar( static_cast<unsigned char>( (value+256) % 256 ) );
142  }
143 
144 
145  // ----------------------------------------------------------------------
151  {
152  return static_cast<int>(readChar());
153  }
154 
155 
156  // ----------------------------------------------------------------------
160  void Storage::writeUnsignedByte(int value)
161  {
162  if (value < 0 || value > 255)
163  {
164  throw std::invalid_argument("Storage::writeUnsignedByte(): Invalid value, not in [0, 255]");
165  }
166  writeChar( static_cast<unsigned char>( value ));
167  }
168 
169 
170  // -----------------------------------------------------------------------
175  std::string Storage::readString()
176  {
177  int len = readInt();
178  checkReadSafe(len);
179  StorageType::const_iterator end = iter_;
180  std::advance(end, len);
181  const std::string tmp(iter_, end);
182  iter_ = end;
183  return tmp;
184  }
185 
186 
187  // ----------------------------------------------------------------------
192  void Storage::writeString(const std::string &s)
193  {
194  writeInt(static_cast<int>(s.length()));
195 
196  store.insert(store.end(), s.begin(), s.end());
197  iter_ = store.begin();
198  }
199 
200 
201  // -----------------------------------------------------------------------
206  std::vector<std::string> Storage::readStringList()
207  {
208  std::vector<std::string> tmp;
209  const int len = readInt();
210  tmp.reserve(len);
211  for (int i = 0; i < len; i++)
212  {
213  tmp.push_back(readString());
214  }
215  return tmp;
216  }
217 
218 
219  // -----------------------------------------------------------------------
224  std::vector<double> Storage::readDoubleList()
225  {
226  std::vector<double> tmp;
227  const int len = readInt();
228  tmp.reserve(len);
229  for (int i = 0; i < len; i++)
230  {
231  tmp.push_back(readDouble());
232  }
233  return tmp;
234  }
235 
236 
237  // ----------------------------------------------------------------------
242  void Storage::writeStringList(const std::vector<std::string> &s)
243  {
244  writeInt(static_cast<int>(s.size()));
245  for (std::vector<std::string>::const_iterator it = s.begin(); it!=s.end() ; it++)
246  {
247  writeString(*it);
248  }
249  }
250 
251 
252  // ----------------------------------------------------------------------
257  void Storage::writeDoubleList(const std::vector<double> &s)
258  {
259  writeInt(static_cast<int>(s.size()));
260  for (std::vector<double>::const_iterator it = s.begin(); it!=s.end() ; it++)
261  {
262  writeDouble(*it);
263  }
264  }
265 
266 
267  // ----------------------------------------------------------------------
275  int Storage::readShort()
276  {
277  short value = 0;
278  unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
279  readByEndianess(p_value, 2);
280  return value;
281  }
282 
283 
284  // ----------------------------------------------------------------------
285  void Storage::writeShort( int value )
286  {
287  if (value < -32768 || value > 32767)
288  {
289  throw std::invalid_argument("Storage::writeShort(): Invalid value, not in [-32768, 32767]");
290  }
291 
292  short svalue = static_cast<short>(value);
293  unsigned char *p_svalue = reinterpret_cast<unsigned char*>(&svalue);
294  writeByEndianess(p_svalue, 2);
295  }
296 
297 
298  // ----------------------------------------------------------------------
306  int Storage::readInt()
307  {
308  int value = 0;
309  unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
310  readByEndianess(p_value, 4);
311  return value;
312  }
313 
314 
315  // ----------------------------------------------------------------------
316  void Storage::writeInt( int value )
317  {
318  unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
319  writeByEndianess(p_value, 4);
320  }
321 
322 
323  // ----------------------------------------------------------------------
331  float Storage::readFloat()
332  {
333  float value = 0;
334  unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
335  readByEndianess(p_value, 4);
336  return value;
337  }
338 
339 
340  // ----------------------------------------------------------------------
341  void Storage::writeFloat( float value )
342  {
343  unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
344  writeByEndianess(p_value, 4);
345  }
346 
347 
348  // ----------------------------------------------------------------------
349  void Storage::writeDouble( double value )
350  {
351  unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
352  writeByEndianess(p_value, 8);
353  }
354 
355 
356  // ----------------------------------------------------------------------
357  double Storage::readDouble( )
358  {
359  double value = 0;
360  unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
361  readByEndianess(p_value, 8);
362  return value;
363  }
364 
365 
366  // ----------------------------------------------------------------------
367  void Storage::writePacket(unsigned char* packet, int length)
368  {
369  store.insert(store.end(), &(packet[0]), &(packet[length]));
370  iter_ = store.begin(); // reserve() invalidates iterators
371  }
372 
373 
374  // ----------------------------------------------------------------------
375  void Storage::writePacket(const std::vector<unsigned char> &packet)
376  {
377  std::copy(packet.begin(), packet.end(), std::back_inserter(store));
378  iter_ = store.begin();
379  }
380 
381 
382  // ----------------------------------------------------------------------
384  {
385  // the compiler cannot deduce to use a const_iterator as source
386  store.insert<StorageType::const_iterator>(store.end(), other.iter_, other.store.end());
387  iter_ = store.begin();
388  }
389 
390 
391  // ----------------------------------------------------------------------
392  void Storage::checkReadSafe(unsigned int num) const
393  {
394  if (std::distance(iter_, store.end()) < static_cast<int>(num))
395  {
396  std::ostringstream msg;
397  msg << "tcpip::Storage::readIsSafe: want to read " << num << " bytes from Storage, "
398  << "but only " << std::distance(iter_, store.end()) << " remaining";
399  throw std::invalid_argument(msg.str());
400  }
401  }
402 
403 
404  // ----------------------------------------------------------------------
405  unsigned char Storage::readCharUnsafe()
406  {
407  char hb = *iter_;
408  ++iter_;
409  return hb;
410  }
411 
412 
413  // ----------------------------------------------------------------------
414  void Storage::writeByEndianess(const unsigned char * begin, unsigned int size)
415  {
416  const unsigned char * end = &(begin[size]);
417  if (bigEndian_)
418  store.insert(store.end(), begin, end);
419  else
420  store.insert(store.end(), std::reverse_iterator<const unsigned char *>(end), std::reverse_iterator<const unsigned char *>(begin));
421  iter_ = store.begin();
422  }
423 
424 
425  // ----------------------------------------------------------------------
426  void Storage::readByEndianess(unsigned char * array, int size)
427  {
429  if (bigEndian_)
430  {
431  for (int i = 0; i < size; ++i)
432  array[i] = readCharUnsafe();
433  }
434  else
435  {
436  for (int i = size - 1; i >= 0; --i)
437  array[i] = readCharUnsafe();
438  }
439  }
440 
441 
442  // ----------------------------------------------------------------------
443  std::string Storage::hexDump() const
444  {
445  static const int width = 2;
446 
447  std::ostringstream dump;
448  // adapt stream attributes
449  // 'showbase' inserts "0x", 'internal' makes leading '0' appear between "0x" and hex digits
450  dump.setf(std::ostream::hex | std::ostream::showbase | std::ostream::internal);
451  dump.fill('0');
452 
453  for(StorageType::const_iterator it = store.begin(); it != store.end(); ++it)
454  {
455  // insert spaces between values
456  if (it != store.begin())
457  dump << " ";
458  dump << std::setw(width) << static_cast<int>(*it);
459  }
460 
461  return dump.str();
462  }
463 
464 }
465 
466 #endif // BUILD_TCPIP
467 
468 /*-----------------------------------------------------------------------
469  * Source $Source: $
470  * Version $Revision: 620 $
471  * Date $Date: 2011-07-08 17:39:10 +0200 (Fri, 08 Jul 2011) $
472  *-----------------------------------------------------------------------
473  * $Log: $
474  *-----------------------------------------------------------------------*/
tcpip::Storage::hexDump
std::string hexDump() const
Dump storage content as series of hex values.
tcpip::Storage::readDouble
virtual double readDouble()
tcpip::Storage::~Storage
virtual ~Storage()
tcpip
Definition: socket.cpp:61
tcpip::Storage::init
void init()
Used in constructors to initialize local variables.
tcpip::Storage::writeUnsignedByte
virtual void writeUnsignedByte(int)
tcpip::Storage::readStringList
virtual std::vector< std::string > readStringList()
tcpip::Storage::valid_pos
virtual bool valid_pos()
tcpip::Storage::writePacket
virtual void writePacket(unsigned char *packet, int length)
tcpip::Storage::end
StorageType::const_iterator end() const
Definition: storage.h:121
tcpip::Storage::readByEndianess
void readByEndianess(unsigned char *array, int size)
Read size elements into array according to endianess.
tcpip::Storage::readChar
virtual unsigned char readChar()
tcpip::Storage::writeByEndianess
void writeByEndianess(const unsigned char *begin, unsigned int size)
Write size elements of array begin according to endianess.
tcpip::Storage::writeByte
virtual void writeByte(int)
tcpip::Storage::readUnsignedByte
virtual int readUnsignedByte()
tcpip::Storage::writeInt
virtual void writeInt(int)
tcpip::Storage::writeChar
virtual void writeChar(unsigned char)
tcpip::Storage::position
virtual unsigned int position() const
tcpip::Storage::readString
virtual std::string readString()
tcpip::Storage::readInt
virtual int readInt()
tcpip::Storage::Storage
Storage()
Standard Constructor.
tcpip::Storage::writeStorage
virtual void writeStorage(tcpip::Storage &store)
tcpip::Storage::writeStringList
virtual void writeStringList(const std::vector< std::string > &s)
tcpip::Storage::store
StorageType store
Definition: storage.h:44
tcpip::Storage::bigEndian_
bool bigEndian_
Definition: storage.h:48
tcpip::Storage::writeFloat
virtual void writeFloat(float)
tcpip::Storage::reset
void reset()
tcpip::Storage::readCharUnsafe
unsigned char readCharUnsafe()
Read a byte without validity check.
tcpip::Storage::writeShort
virtual void writeShort(int)
tcpip::Storage::writeString
virtual void writeString(const std::string &s)
tcpip::Storage::begin
StorageType::const_iterator begin() const
Definition: storage.h:120
storage.h
tcpip::Storage::checkReadSafe
void checkReadSafe(unsigned int num) const
Check if the next num bytes can be read safely.
tcpip::Storage::writeDoubleList
virtual void writeDoubleList(const std::vector< double > &s)
tcpip::Storage::size
StorageType::size_type size() const
Definition: storage.h:118
tcpip::Storage::readByte
virtual int readByte()
tcpip::Storage::writeDouble
virtual void writeDouble(double)
tcpip::Storage::iter_
StorageType::const_iterator iter_
Definition: storage.h:45
tcpip::Storage::readFloat
virtual float readFloat()
tcpip::Storage::readShort
virtual int readShort()
tcpip::Storage::readDoubleList
virtual std::vector< double > readDoubleList()
tcpip::Storage
Definition: storage.h:37