LCOV - code coverage report
Current view: top level - src/foreign/tcpip - storage.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 74.4 % 160 119
Test Date: 2024-11-20 15:55:46 Functions: 81.1 % 37 30

            Line data    Source code
       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              :         // ----------------------------------------------------------------------
      32     44101602 :         Storage::Storage()
      33              :         {
      34     44101602 :                 init();
      35     44101602 :         }
      36              : 
      37              : 
      38              :         // ----------------------------------------------------------------------
      39     18340300 :         Storage::Storage(const unsigned char packet[], int length)
      40              :         {
      41              :                 assert(length >= 0); // fixed MB, 2015-04-21
      42              : 
      43     18340300 :                 store.reserve(length);
      44              :                 // Get the content
      45     91701500 :                 for(int i = 0; i < length; ++i) store.push_back(packet[i]);
      46              : 
      47     18340300 :                 init();
      48     18340300 :         }
      49              : 
      50              : 
      51              :         // ----------------------------------------------------------------------
      52     62441902 :         void Storage::init()
      53              :         {
      54              :                 // Initialize local variables
      55     62441902 :                 iter_ = store.begin();
      56              : 
      57              :                 short a = 0x0102;
      58              :                 unsigned char *p_a = reinterpret_cast<unsigned char*>(&a);
      59     62441902 :                 bigEndian_ = (p_a[0] == 0x01); // big endian?
      60     62441902 :         }
      61              : 
      62              : 
      63              :         // ----------------------------------------------------------------------
      64     62441892 :         Storage::~Storage()
      65     62441892 :         {}
      66              : 
      67              : 
      68              :         // ----------------------------------------------------------------------
      69    352917399 :         bool Storage::valid_pos()
      70              :         {
      71    352917399 :                 return (iter_ != store.end());   // this implies !store.empty()
      72              :         }
      73              : 
      74              : 
      75              :         // ----------------------------------------------------------------------
      76     28583300 :         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     28583300 :                 return static_cast<unsigned int>(std::distance(store.begin(), iter_));
      81              :         }
      82              : 
      83              : 
      84              :         // ----------------------------------------------------------------------
      85     80819317 :         void Storage::reset() {
      86              :                 store.clear();
      87     80819317 :                 iter_ = store.begin();
      88     80819317 :         }
      89              : 
      90              : 
      91              :         // ----------------------------------------------------------------------
      92       250172 :         void Storage::resetPos() {
      93       250172 :                 iter_ = store.begin();
      94       250172 :         }
      95              : 
      96              : 
      97              :         // ----------------------------------------------------------------------
      98              :         /**
      99              :         * Reads a char form the array
     100              :         * @return The read char (between 0 and 255)
     101              :         */
     102    271899313 :         unsigned char Storage::readChar()
     103              :         {
     104    271899313 :                 if ( !valid_pos() )
     105              :                 {
     106            0 :                         throw std::invalid_argument("Storage::readChar(): invalid position");
     107              :                 }
     108    271899313 :                 return readCharUnsafe();
     109              :         }
     110              : 
     111              : 
     112              :         // ----------------------------------------------------------------------
     113              :         /**
     114              :         *
     115              :         */
     116    318013952 :         void Storage::writeChar(unsigned char value)
     117              :         {
     118    318013952 :                 store.push_back(value);
     119    318013952 :                 iter_ = store.begin();
     120    318013952 :         }
     121              : 
     122              : 
     123              :         // ----------------------------------------------------------------------
     124              :         /**
     125              :         * Reads a byte form the array
     126              :         * @return The read byte (between -128 and 127)
     127              :         */
     128     28490108 :         int Storage::readByte()
     129              :         {
     130     28490108 :                 int i = static_cast<int>(readChar());
     131     28490108 :                 if (i < 128) return i;
     132      2264616 :                 else return (i - 256);
     133              :         }
     134              : 
     135              : 
     136              :         // ----------------------------------------------------------------------
     137              :         /**
     138              :         *
     139              :         */
     140     28279332 :         void Storage::writeByte(int value)
     141              :         {
     142     28279332 :                 if (value < -128 || value > 127)
     143              :                 {
     144            0 :                         throw std::invalid_argument("Storage::writeByte(): Invalid value, not in [-128, 127]");
     145              :                 }
     146     28279332 :                 writeChar( static_cast<unsigned char>( (value+256) % 256 ) );
     147     28279332 :         }
     148              : 
     149              : 
     150              :         // ----------------------------------------------------------------------
     151              :         /**
     152              :         * Reads an unsigned byte form the array
     153              :         * @return The read byte (between 0 and 255)
     154              :         */
     155    243408057 :         int Storage::readUnsignedByte()
     156              :         {
     157    243408057 :                 return static_cast<int>(readChar());
     158              :         }
     159              : 
     160              : 
     161              :         // ----------------------------------------------------------------------
     162              :         /**
     163              :         *
     164              :         */
     165    289649633 :         void Storage::writeUnsignedByte(int value)
     166              :         {
     167    289649633 :                 if (value < 0 || value > 255)
     168              :                 {
     169            0 :                         throw std::invalid_argument("Storage::writeUnsignedByte(): Invalid value, not in [0, 255]");
     170              :                 }
     171    289649633 :                 writeChar( static_cast<unsigned char>( value ));
     172    289649633 :         }
     173              : 
     174              : 
     175              :         // -----------------------------------------------------------------------
     176              :         /**
     177              :         * Reads a string form the array
     178              :         * @return The read string
     179              :         */
     180     28795835 :         std::string Storage::readString()
     181              :         {
     182     28795835 :                 int len = readInt();
     183     28795835 :                 checkReadSafe(len);
     184     28795835 :                 StorageType::const_iterator end = iter_;
     185              :                 std::advance(end, len);
     186     28795835 :                 const std::string tmp(iter_, end);
     187     28795835 :                 iter_ = end;
     188     28795835 :                 return tmp;
     189              :         }
     190              : 
     191              : 
     192              :         // ----------------------------------------------------------------------
     193              :         /**
     194              :         * Writes a string into the array;
     195              :         * @param s              The string to be written
     196              :         */
     197     62955727 :         void Storage::writeString(const std::string &s)
     198              :         {
     199     62955727 :                 writeInt(static_cast<int>(s.length()));
     200              : 
     201     62955727 :                 store.insert(store.end(), s.begin(), s.end());
     202     62955727 :                 iter_ = store.begin();
     203     62955727 :         }
     204              : 
     205              : 
     206              :     // -----------------------------------------------------------------------
     207              :     /**
     208              :     * Reads a string list form the array
     209              :     * @return The read string
     210              :     */
     211        58180 :     std::vector<std::string> Storage::readStringList()
     212              :     {
     213              :         std::vector<std::string> tmp;
     214        58180 :         const int len = readInt();
     215        58180 :         tmp.reserve(len);
     216       435585 :         for (int i = 0; i < len; i++)
     217              :         {
     218       754810 :             tmp.push_back(readString());
     219              :         }
     220        58180 :         return tmp;
     221            0 :     }
     222              : 
     223              : 
     224              :     // -----------------------------------------------------------------------
     225              :     /**
     226              :     * Reads a double list from the array
     227              :     * @return The read double list
     228              :     */
     229          212 :     std::vector<double> Storage::readDoubleList()
     230              :     {
     231              :         std::vector<double> tmp;
     232          212 :         const int len = readInt();
     233          212 :         tmp.reserve(len);
     234          862 :         for (int i = 0; i < len; i++)
     235              :         {
     236          650 :             tmp.push_back(readDouble());
     237              :         }
     238          212 :         return tmp;
     239            0 :     }
     240              : 
     241              : 
     242              :     // ----------------------------------------------------------------------
     243              :     /**
     244              :     * Writes a string into the array;
     245              :     * @param s      The string to be written
     246              :     */
     247       244552 :     void Storage::writeStringList(const std::vector<std::string> &s)
     248              :     {
     249       244552 :         writeInt(static_cast<int>(s.size()));
     250      1231931 :         for (std::vector<std::string>::const_iterator it = s.begin(); it!=s.end() ; it++)
     251              :         {
     252       987379 :             writeString(*it);
     253              :         }
     254       244552 :     }
     255              : 
     256              : 
     257              :     // ----------------------------------------------------------------------
     258              :     /**
     259              :     * Writes a double list into the array;
     260              :     * @param s      The double list  to be written
     261              :     */
     262            6 :     void Storage::writeDoubleList(const std::vector<double> &s)
     263              :     {
     264            6 :         writeInt(static_cast<int>(s.size()));
     265           12 :         for (std::vector<double>::const_iterator it = s.begin(); it!=s.end() ; it++)
     266              :         {
     267            6 :             writeDouble(*it);
     268              :         }
     269            6 :     }
     270              : 
     271              : 
     272              :         // ----------------------------------------------------------------------
     273              :         /**
     274              :         * Restores an integer, which was split up in two bytes according to the
     275              :         * specification, it must have been split by its row byte representation
     276              :         * with MSBF-order
     277              :         *
     278              :         * @return the unspoiled integer value (between -32768 and 32767)
     279              :         */
     280            0 :         int Storage::readShort()
     281              :         {
     282            0 :                 short value = 0;
     283              :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     284            0 :                 readByEndianess(p_value, 2);
     285            0 :                 return value;
     286              :         }
     287              : 
     288              : 
     289              :         // ----------------------------------------------------------------------
     290            0 :         void Storage::writeShort( int value )
     291              :         {
     292            0 :                 if (value < -32768 || value > 32767)
     293              :                 {
     294            0 :                         throw std::invalid_argument("Storage::writeShort(): Invalid value, not in [-32768, 32767]");
     295              :                 }
     296              : 
     297            0 :                 short svalue = static_cast<short>(value);
     298              :                 unsigned char *p_svalue = reinterpret_cast<unsigned char*>(&svalue);
     299            0 :                 writeByEndianess(p_svalue, 2);
     300            0 :         }
     301              : 
     302              : 
     303              :         // ----------------------------------------------------------------------
     304              :         /**
     305              :         * restores an integer, which was split up in four bytes acording to the
     306              :         * specification, it must have been split by its row byte representation
     307              :         * with MSBF-order
     308              :         *
     309              :         * @return the unspoiled integer value (between -2.147.483.648 and 2.147.483.647)
     310              :         */
     311     47757136 :         int Storage::readInt()
     312              :         {
     313     47757136 :                 int value = 0;
     314              :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     315     47757136 :                 readByEndianess(p_value, 4);
     316     47757136 :                 return value;
     317              :         }
     318              : 
     319              : 
     320              :         // ----------------------------------------------------------------------
     321    102114221 :         void Storage::writeInt( int value )
     322              :         {
     323              :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     324    102114221 :                 writeByEndianess(p_value, 4);
     325    102114221 :         }
     326              : 
     327              : 
     328              :         // ----------------------------------------------------------------------
     329              :         /**
     330              :         * restores a float , which was split up in four bytes acording to the
     331              :         * specification, it must have been split by its row byte representation
     332              :         * with MSBF-order
     333              :         *
     334              :         * @return the unspoiled float value
     335              :         */
     336            0 :         float Storage::readFloat()
     337              :         {
     338            0 :                 float value = 0;
     339              :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     340            0 :                 readByEndianess(p_value, 4);
     341            0 :                 return value;
     342              :         }
     343              : 
     344              : 
     345              :         // ----------------------------------------------------------------------
     346            0 :         void Storage::writeFloat( float value )
     347              :         {
     348              :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     349            0 :                 writeByEndianess(p_value, 4);
     350            0 :         }
     351              : 
     352              : 
     353              :         // ----------------------------------------------------------------------
     354      6608187 :         void Storage::writeDouble( double value )
     355              :         {
     356              :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     357      6608187 :                 writeByEndianess(p_value, 8);
     358      6608187 :         }
     359              : 
     360              : 
     361              :         // ----------------------------------------------------------------------
     362      9475253 :         double Storage::readDouble( )
     363              :         {
     364      9475253 :                 double value = 0;
     365              :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     366      9475253 :                 readByEndianess(p_value, 8);
     367      9475253 :                 return value;
     368              :         }
     369              : 
     370              : 
     371              :         // ----------------------------------------------------------------------
     372     18340300 :         void Storage::writePacket(unsigned char* packet, int length)
     373              :         {
     374     18340300 :                 store.insert(store.end(), &(packet[0]), &(packet[length]));
     375     18340300 :                 iter_ = store.begin();   // reserve() invalidates iterators
     376     18340300 :         }
     377              : 
     378              : 
     379              :         // ----------------------------------------------------------------------
     380            0 :     void Storage::writePacket(const std::vector<unsigned char> &packet)
     381              :     {
     382            0 :         std::copy(packet.begin(), packet.end(), std::back_inserter(store));
     383            0 :                 iter_ = store.begin();
     384            0 :     }
     385              : 
     386              : 
     387              :         // ----------------------------------------------------------------------
     388     34484990 :         void Storage::writeStorage(tcpip::Storage& other)
     389              :         {
     390              :                 // the compiler cannot deduce to use a const_iterator as source
     391     34484990 :                 store.insert<StorageType::const_iterator>(store.end(), other.iter_, other.store.end());
     392     34484990 :                 iter_ = store.begin();
     393     34484990 :         }
     394              : 
     395              : 
     396              :         // ----------------------------------------------------------------------
     397     86028224 :         void Storage::checkReadSafe(unsigned int num) const
     398              :         {
     399     86028224 :                 if (std::distance(iter_, store.end()) < static_cast<int>(num))
     400              :                 {
     401            0 :                         std::ostringstream msg;
     402              :                         msg << "tcpip::Storage::readIsSafe: want to read "  << num << " bytes from Storage, "
     403            0 :                                 << "but only " << std::distance(iter_, store.end()) << " remaining";
     404            0 :                         throw std::invalid_argument(msg.str());
     405            0 :                 }
     406     86028224 :         }
     407              : 
     408              : 
     409              :         // ----------------------------------------------------------------------
     410    538729881 :         unsigned char Storage::readCharUnsafe()
     411              :         {
     412    538729881 :                 const unsigned char hb = *iter_;
     413              :                 ++iter_;
     414    538729881 :                 return hb;
     415              :         }
     416              : 
     417              : 
     418              :         // ----------------------------------------------------------------------
     419    108722408 :         void Storage::writeByEndianess(const unsigned char * begin, unsigned int size)
     420              :         {
     421    108722408 :                 const unsigned char * end = &(begin[size]);
     422    108722408 :                 if (bigEndian_)
     423            0 :                         store.insert(store.end(), begin, end);
     424              :                 else
     425    108722408 :                         store.insert(store.end(), std::reverse_iterator<const unsigned char *>(end), std::reverse_iterator<const unsigned char *>(begin));
     426    108722408 :                 iter_ = store.begin();
     427    108722408 :         }
     428              : 
     429              : 
     430              :         // ----------------------------------------------------------------------
     431     57232389 :         void Storage::readByEndianess(unsigned char * array, int size)
     432              :         {
     433     57232389 :                 checkReadSafe(size);
     434     57232389 :                 if (bigEndian_)
     435              :                 {
     436            0 :                         for (int i = 0; i < size; ++i)
     437            0 :                                 array[i] = readCharUnsafe();
     438              :                 }
     439              :                 else
     440              :                 {
     441    324062957 :                         for (int i = size - 1; i >= 0; --i)
     442    266830568 :                                 array[i] = readCharUnsafe();
     443              :                 }
     444     57232389 :         }
     445              : 
     446              : 
     447              :         // ----------------------------------------------------------------------
     448            0 :         std::string Storage::hexDump() const
     449              :         {
     450            0 :                 std::ostringstream dump;
     451            0 :                 for(StorageType::const_iterator it = store.begin(); it != store.end(); ++it)
     452              :                 {
     453              :                         // insert spaces between values
     454            0 :                         if (it != store.begin())
     455            0 :                                 dump << " ";
     456            0 :                         dump << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(*it);
     457              :                 }
     458              : 
     459            0 :                 return dump.str();
     460            0 :         }
     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              :  *-----------------------------------------------------------------------*/
        

Generated by: LCOV version 2.0-1