LCOV - code coverage report
Current view: top level - src/foreign/tcpip - storage.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 118 158 74.7 %
Date: 2024-05-07 15:28:01 Functions: 30 37 81.1 %

          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    69189796 :         Storage::Storage()
      33             :         {
      34    69189796 :                 init();
      35    69189796 :         }
      36             : 
      37             : 
      38             :         // ----------------------------------------------------------------------
      39    17234860 :         Storage::Storage(const unsigned char packet[], int length)
      40             :         {
      41             :                 assert(length >= 0); // fixed MB, 2015-04-21
      42             : 
      43    17234860 :                 store.reserve(length);
      44             :                 // Get the content
      45    86174300 :                 for(int i = 0; i < length; ++i) store.push_back(packet[i]);
      46             : 
      47    17234860 :                 init();
      48    17234860 :         }
      49             : 
      50             : 
      51             :         // ----------------------------------------------------------------------
      52    86424656 :         void Storage::init()
      53             :         {
      54             :                 // Initialize local variables
      55    86424656 :                 iter_ = store.begin();
      56             : 
      57             :                 short a = 0x0102;
      58             :                 unsigned char *p_a = reinterpret_cast<unsigned char*>(&a);
      59    86424656 :                 bigEndian_ = (p_a[0] == 0x01); // big endian?
      60    86424656 :         }
      61             : 
      62             : 
      63             :         // ----------------------------------------------------------------------
      64    86424646 :         Storage::~Storage()
      65    86424646 :         {}
      66             : 
      67             : 
      68             :         // ----------------------------------------------------------------------
      69   605051546 :         bool Storage::valid_pos()
      70             :         {
      71   605051546 :                 return (iter_ != store.end());   // this implies !store.empty()
      72             :         }
      73             : 
      74             : 
      75             :         // ----------------------------------------------------------------------
      76    27365442 :         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    27365442 :                 return static_cast<unsigned int>(std::distance(store.begin(), iter_));
      81             :         }
      82             : 
      83             : 
      84             :         // ----------------------------------------------------------------------
      85    84912911 :         void Storage::reset() {
      86             :                 store.clear();
      87    84912911 :                 iter_ = store.begin();
      88    84912911 :         }
      89             : 
      90             : 
      91             :         // ----------------------------------------------------------------------
      92      250042 :         void Storage::resetPos() {
      93      250042 :                 iter_ = store.begin();
      94      250042 :         }
      95             : 
      96             : 
      97             :         // ----------------------------------------------------------------------
      98             :         /**
      99             :         * Reads a char form the array
     100             :         * @return The read char (between 0 and 255)
     101             :         */
     102   497827771 :         unsigned char Storage::readChar()
     103             :         {
     104   497827771 :                 if ( !valid_pos() )
     105             :                 {
     106           0 :                         throw std::invalid_argument("Storage::readChar(): invalid position");
     107             :                 }
     108   497827771 :                 return readCharUnsafe();
     109             :         }
     110             : 
     111             : 
     112             :         // ----------------------------------------------------------------------
     113             :         /**
     114             :         *
     115             :         */
     116   545490680 :         void Storage::writeChar(unsigned char value)
     117             :         {
     118   545490680 :                 store.push_back(value);
     119   545490680 :                 iter_ = store.begin();
     120   545490680 :         }
     121             : 
     122             : 
     123             :         // ----------------------------------------------------------------------
     124             :         /**
     125             :         * Reads a byte form the array
     126             :         * @return The read byte (between -128 and 127)
     127             :         */
     128    58449437 :         int Storage::readByte()
     129             :         {
     130    58449437 :                 int i = static_cast<int>(readChar());
     131    58449437 :                 if (i < 128) return i;
     132     4672773 :                 else return (i - 256);
     133             :         }
     134             : 
     135             : 
     136             :         // ----------------------------------------------------------------------
     137             :         /**
     138             :         *
     139             :         */
     140    58072907 :         void Storage::writeByte(int value)
     141             :         {
     142    58072907 :                 if (value < -128 || value > 127)
     143             :                 {
     144           0 :                         throw std::invalid_argument("Storage::writeByte(): Invalid value, not in [-128, 127]");
     145             :                 }
     146    58072907 :                 writeChar( static_cast<unsigned char>( (value+256) % 256 ) );
     147    58072907 :         }
     148             : 
     149             : 
     150             :         // ----------------------------------------------------------------------
     151             :         /**
     152             :         * Reads an unsigned byte form the array
     153             :         * @return The read byte (between 0 and 255)
     154             :         */
     155   439377249 :         int Storage::readUnsignedByte()
     156             :         {
     157   439377249 :                 return static_cast<int>(readChar());
     158             :         }
     159             : 
     160             : 
     161             :         // ----------------------------------------------------------------------
     162             :         /**
     163             :         *
     164             :         */
     165   487292925 :         void Storage::writeUnsignedByte(int value)
     166             :         {
     167   487292925 :                 if (value < 0 || value > 255)
     168             :                 {
     169           0 :                         throw std::invalid_argument("Storage::writeUnsignedByte(): Invalid value, not in [0, 255]");
     170             :                 }
     171   487292925 :                 writeChar( static_cast<unsigned char>( value ));
     172   487292925 :         }
     173             : 
     174             : 
     175             :         // -----------------------------------------------------------------------
     176             :         /**
     177             :         * Reads a string form the array
     178             :         * @return The read string
     179             :         */
     180    46492087 :         std::string Storage::readString()
     181             :         {
     182    46492087 :                 int len = readInt();
     183    46492087 :                 checkReadSafe(len);
     184    46492087 :                 StorageType::const_iterator end = iter_;
     185             :                 std::advance(end, len);
     186             :                 const std::string tmp(iter_, end);
     187    46492087 :                 iter_ = end;
     188    46492087 :                 return tmp;
     189             :         }
     190             : 
     191             : 
     192             :         // ----------------------------------------------------------------------
     193             :         /**
     194             :         * Writes a string into the array;
     195             :         * @param s              The string to be written
     196             :         */
     197    97201480 :         void Storage::writeString(const std::string &s)
     198             :         {
     199    97201480 :                 writeInt(static_cast<int>(s.length()));
     200             : 
     201    97201480 :                 store.insert(store.end(), s.begin(), s.end());
     202    97201480 :                 iter_ = store.begin();
     203    97201480 :         }
     204             : 
     205             : 
     206             :     // -----------------------------------------------------------------------
     207             :     /**
     208             :     * Reads a string list form the array
     209             :     * @return The read string
     210             :     */
     211       57440 :     std::vector<std::string> Storage::readStringList()
     212             :     {
     213             :         std::vector<std::string> tmp;
     214       57440 :         const int len = readInt();
     215       57440 :         tmp.reserve(len);
     216      434953 :         for (int i = 0; i < len; i++)
     217             :         {
     218      755026 :             tmp.push_back(readString());
     219             :         }
     220       57440 :         return tmp;
     221           0 :     }
     222             : 
     223             : 
     224             :     // -----------------------------------------------------------------------
     225             :     /**
     226             :     * Reads a double list from the array
     227             :     * @return The read double list
     228             :     */
     229         282 :     std::vector<double> Storage::readDoubleList()
     230             :     {
     231             :         std::vector<double> tmp;
     232         282 :         const int len = readInt();
     233         282 :         tmp.reserve(len);
     234        1148 :         for (int i = 0; i < len; i++)
     235             :         {
     236         866 :             tmp.push_back(readDouble());
     237             :         }
     238         282 :         return tmp;
     239             :     }
     240             : 
     241             : 
     242             :     // ----------------------------------------------------------------------
     243             :     /**
     244             :     * Writes a string into the array;
     245             :     * @param s      The string to be written
     246             :     */
     247      393386 :     void Storage::writeStringList(const std::vector<std::string> &s)
     248             :     {
     249      393386 :         writeInt(static_cast<int>(s.size()));
     250     1918447 :         for (std::vector<std::string>::const_iterator it = s.begin(); it!=s.end() ; it++)
     251             :         {
     252     1525061 :             writeString(*it);
     253             :         }
     254      393386 :     }
     255             : 
     256             : 
     257             :     // ----------------------------------------------------------------------
     258             :     /**
     259             :     * Writes a double list into the array;
     260             :     * @param s      The double list  to be written
     261             :     */
     262           8 :     void Storage::writeDoubleList(const std::vector<double> &s)
     263             :     {
     264           8 :         writeInt(static_cast<int>(s.size()));
     265          16 :         for (std::vector<double>::const_iterator it = s.begin(); it!=s.end() ; it++)
     266             :         {
     267           8 :             writeDouble(*it);
     268             :         }
     269           8 :     }
     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    64586038 :         int Storage::readInt()
     312             :         {
     313    64586038 :                 int value = 0;
     314             :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     315    64586038 :                 readByEndianess(p_value, 4);
     316    64586038 :                 return value;
     317             :         }
     318             : 
     319             : 
     320             :         // ----------------------------------------------------------------------
     321   137829663 :         void Storage::writeInt( int value )
     322             :         {
     323             :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     324   137829663 :                 writeByEndianess(p_value, 4);
     325   137829663 :         }
     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    12166195 :         void Storage::writeDouble( double value )
     355             :         {
     356             :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     357    12166195 :                 writeByEndianess(p_value, 8);
     358    12166195 :         }
     359             : 
     360             : 
     361             :         // ----------------------------------------------------------------------
     362     8703472 :         double Storage::readDouble( )
     363             :         {
     364     8703472 :                 double value = 0;
     365             :                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
     366     8703472 :                 readByEndianess(p_value, 8);
     367     8703472 :                 return value;
     368             :         }
     369             : 
     370             : 
     371             :         // ----------------------------------------------------------------------
     372    17234860 :         void Storage::writePacket(unsigned char* packet, int length)
     373             :         {
     374    17234860 :                 store.insert(store.end(), &(packet[0]), &(packet[length]));
     375    17234860 :                 iter_ = store.begin();   // reserve() invalidates iterators
     376    17234860 :         }
     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    50643159 :         void Storage::writeStorage(tcpip::Storage& other)
     389             :         {
     390             :                 // the compiler cannot deduce to use a const_iterator as source
     391    50643159 :                 store.insert<StorageType::const_iterator>(store.end(), other.iter_, other.store.end());
     392    50643159 :                 iter_ = store.begin();
     393    50643159 :         }
     394             : 
     395             : 
     396             :         // ----------------------------------------------------------------------
     397   119781597 :         void Storage::checkReadSafe(unsigned int num) const
     398             :         {
     399   119781597 :                 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   119781597 :         }
     407             : 
     408             : 
     409             :         // ----------------------------------------------------------------------
     410   825799699 :         unsigned char Storage::readCharUnsafe()
     411             :         {
     412   825799699 :                 const unsigned char hb = *iter_;
     413             :                 ++iter_;
     414   825799699 :                 return hb;
     415             :         }
     416             : 
     417             : 
     418             :         // ----------------------------------------------------------------------
     419   149995858 :         void Storage::writeByEndianess(const unsigned char * begin, unsigned int size)
     420             :         {
     421   149995858 :                 const unsigned char * end = &(begin[size]);
     422   149995858 :                 if (bigEndian_)
     423           0 :                         store.insert(store.end(), begin, end);
     424             :                 else
     425   149995858 :                         store.insert(store.end(), std::reverse_iterator<const unsigned char *>(end), std::reverse_iterator<const unsigned char *>(begin));
     426   149995858 :                 iter_ = store.begin();
     427   149995858 :         }
     428             : 
     429             : 
     430             :         // ----------------------------------------------------------------------
     431    73289510 :         void Storage::readByEndianess(unsigned char * array, int size)
     432             :         {
     433    73289510 :                 checkReadSafe(size);
     434    73289510 :                 if (bigEndian_)
     435             :                 {
     436           0 :                         for (int i = 0; i < size; ++i)
     437           0 :                                 array[i] = readCharUnsafe();
     438             :                 }
     439             :                 else
     440             :                 {
     441   401261438 :                         for (int i = size - 1; i >= 0; --i)
     442   327971928 :                                 array[i] = readCharUnsafe();
     443             :                 }
     444    73289510 :         }
     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 1.14