storage.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002  ** This file is part of the network simulator Shawn.                  **
00003  ** Copyright (C) 2004-2007 by the SwarmNet (www.swarmnet.de) project  **
00004  ** Shawn is free software; you can redistribute it and/or modify it   **
00005  ** under the terms of the BSD License. Refer to the shawn-licence.txt **
00006  ** file in the root of the Shawn source tree for further details.     **
00007  ************************************************************************
00008  **                                                                    **
00009  ** \author Axel Wegener <wegener@itm.uni-luebeck.de>                  **
00010  **                                                                    **
00011  ************************************************************************/
00012 
00013 #include "storage.h"
00014 
00015 #ifdef BUILD_TCPIP
00016 
00017 #include <iostream>
00018 
00019 
00020 using namespace std;
00021 
00022 //#define NULLITER static_cast<list<unsigned char>::iterator>(0)
00023 
00024 namespace tcpip
00025 {
00026 
00027     // ----------------------------------------------------------------------
00028     Storage::Storage()
00029     {
00030         init();
00031     }
00032 
00033     // ----------------------------------------------------------------------
00034     Storage::Storage(unsigned char packet[], int length)
00035     {
00036         // Length is calculated, if -1, or given
00037         if (length == -1) length = sizeof(packet) / sizeof(unsigned char);
00038         
00039         store.reserve(length);
00040         // Get the content
00041         for(int i = 0; i < length; ++i) store.push_back(packet[i]);
00042 
00043         init();
00044     }
00045 
00046 
00047     // ----------------------------------------------------------------------
00048     void Storage::init()
00049     {
00050         // Initialize local variables
00051         pos_=0;
00052         iterValid_ = iterEndValid_ = false;
00053         valid_pos();
00054 
00055         short a = 0x0102;
00056         unsigned char *p_a = reinterpret_cast<unsigned char*>(&a);
00057         bigEndian_ = (p_a[0] == 0x01); // big endian?
00058     }
00059 
00060     // ----------------------------------------------------------------------
00061     Storage::~Storage()
00062     {}
00063 
00064     // ----------------------------------------------------------------------
00065     bool Storage::valid_pos()
00066     {
00067         if (size() == 0) return false;
00068 
00069         // Check iterator iterEnd_ for validity
00070         if ( !iterEndValid_ )
00071         {
00072             iterEnd_ = store.end();
00073             iterEndValid_ = true;
00074         }
00075 
00076         // Check Iterator iter_ for validity
00077         if ( !iterValid_ ) 
00078         {
00079             iter_ = store.begin();
00080             unsigned int i = 0;
00081             while ( i < pos_ 
00082                 && iter_ != iterEnd_)
00083             {
00084                 ++i;
00085                 ++iter_;
00086             }
00087             iterValid_ = true;
00088         }
00089 
00090         return (iter_ != iterEnd_);
00091     }
00092 
00093     // ----------------------------------------------------------------------
00094     unsigned int Storage::position() const
00095     {
00096         // pos_ contains everytime the correct position, 
00097         // even if iterValid == false
00098         return pos_;
00099     }
00100 
00101     // ----------------------------------------------------------------------
00102     void Storage::reset()
00103     {
00104         store.clear();
00105         pos_=0;
00106         iterValid_ = false;
00107         iterEndValid_ = false;
00108     }
00109 
00110     // ----------------------------------------------------------------------
00115     unsigned char Storage::readChar() throw(std::invalid_argument)
00116     {
00117         if ( !valid_pos() )
00118         {
00119             throw std::invalid_argument("Storage::readChar(): invalid position");
00120         }
00121         char hb = *iter_;
00122         ++iter_;
00123         ++pos_;
00124         return hb;
00125     }
00126 
00127     // ----------------------------------------------------------------------
00131     void Storage::writeChar(unsigned char value) throw()
00132     {
00133         store.push_back(value);
00134     }
00135 
00136     // ----------------------------------------------------------------------
00141     int Storage::readByte() throw(std::invalid_argument)
00142     {
00143         int i = static_cast<int>(readChar());
00144         if (i < 128) return i; 
00145         else return (i - 256);
00146     }
00147 
00148     // ----------------------------------------------------------------------
00152     void Storage::writeByte(int value) throw(std::invalid_argument)
00153     {
00154         if (value < -128 || value > 127)
00155         {
00156             throw std::invalid_argument("Storage::writeByte(): Invalid value, not in [-128, 127]");
00157         }
00158         writeChar( static_cast<unsigned char>( (value+256) % 256 ) );
00159     }
00160 
00161     // ----------------------------------------------------------------------
00166     int Storage::readUnsignedByte() throw(std::invalid_argument)
00167     {
00168         return static_cast<int>(readChar());
00169     }
00170 
00171     // ----------------------------------------------------------------------
00175     void Storage::writeUnsignedByte(int value) throw(std::invalid_argument)
00176     {
00177         if (value < 0 || value > 255)
00178         {
00179             throw std::invalid_argument("Storage::writeUnsignedByte(): Invalid value, not in [0, 255]");
00180         }
00181         writeChar( static_cast<unsigned char>( value ));
00182     }
00183 
00184     // -----------------------------------------------------------------------
00189     std::string Storage::readString() throw(std::invalid_argument)
00190     {
00191         string tmp;
00192         int len = readInt();
00193         for (int i = 0; i < len; i++) {
00194             tmp += (char) readChar();
00195         }
00196         return tmp;
00197     }
00198 
00199     // ----------------------------------------------------------------------
00204     void Storage::writeString(std::string s) throw()
00205     {
00206         writeInt(static_cast<int>(s.length()));
00207         for (string::iterator it = s.begin(); it!=s.end() ; it++) {
00208             writeChar(*it);
00209         }
00210     }
00211 
00212     // -----------------------------------------------------------------------
00217     std::vector<std::string> Storage::readStringList() throw(std::invalid_argument)
00218     {
00219         std::vector<std::string> tmp;
00220         int len = readInt();
00221         for (int i = 0; i < len; i++) {
00222             tmp.push_back(readString());
00223         }
00224         return tmp;
00225     }
00226 
00227     // ----------------------------------------------------------------------
00232     void Storage::writeStringList(const std::vector<std::string> &s) throw()
00233     {
00234         writeInt(static_cast<int>(s.size()));
00235         for (std::vector<std::string>::const_iterator it = s.begin(); it!=s.end() ; it++) {
00236             writeString(*it);
00237         }
00238     }
00239 
00240     // ----------------------------------------------------------------------
00248     int Storage::readShort() throw(std::invalid_argument)
00249     {
00250                 short value = 0;
00251                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
00252                 if (bigEndian_)
00253                 {
00254                         // network is big endian
00255                         p_value[0] = readChar();
00256                         p_value[1] = readChar();
00257                 } else {
00258                         // network is big endian
00259                         p_value[1] = readChar();
00260                         p_value[0] = readChar();
00261                 }
00262                 return value;
00263         }
00264 
00265     // ----------------------------------------------------------------------
00266     void Storage::writeShort( int value ) throw(std::invalid_argument)
00267     {
00268         if (value < -32768 || value > 32767)
00269         {
00270             throw std::invalid_argument("Storage::writeShort(): Invalid value, not in [-32768, 32767]");
00271         }
00272 
00273         short svalue = static_cast<short>(value);
00274         //assert(svalue == value);
00275 
00276                 unsigned char *p_svalue = reinterpret_cast<unsigned char*>(&svalue);
00277                 if (bigEndian_)
00278                 {
00279                         // network is big endian
00280                         writeChar(p_svalue[0]);
00281                         writeChar(p_svalue[1]);
00282                 } else {
00283                        // network is big endian
00284                        writeChar(p_svalue[1]);
00285                        writeChar(p_svalue[0]);
00286                 }
00287     }
00288 
00289     // ----------------------------------------------------------------------
00290 
00291     /*
00292     * restores an integer, which was split up in four bytes acording to the
00293     * specification, it must have been split by its row byte representation
00294     * with MSBF-order
00295     *
00296     * @return the unspoiled integer value (between -2.147.483.648 and 2.147.483.647)
00297     */
00298     int Storage::readInt() throw(std::invalid_argument)
00299     {
00300                 int value = 0;
00301                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
00302                 if (bigEndian_)
00303                 {
00304                         // network is big endian
00305                         p_value[0] = readChar();
00306                         p_value[1] = readChar();
00307                         p_value[2] = readChar();
00308                         p_value[3] = readChar();
00309                 } else {
00310                         // network is big endian
00311                         p_value[3] = readChar();
00312                         p_value[2] = readChar();
00313                         p_value[1] = readChar();
00314                         p_value[0] = readChar();
00315                 }
00316                 return value;
00317     }
00318 
00319     // ----------------------------------------------------------------------
00320     void Storage::writeInt( int value ) throw()
00321     {
00322                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
00323                 if (bigEndian_)
00324                 {
00325                         // network is big endian
00326                         writeChar(p_value[0]);
00327                         writeChar(p_value[1]);
00328                         writeChar(p_value[2]);
00329                         writeChar(p_value[3]);
00330                 } else {
00331                         // network is big endian
00332                         writeChar(p_value[3]);
00333                         writeChar(p_value[2]);
00334                         writeChar(p_value[1]);
00335                         writeChar(p_value[0]);
00336                 }
00337     }
00338 
00339     // ----------------------------------------------------------------------
00340 
00341     /*
00342     * restores a float , which was split up in four bytes acording to the
00343     * specification, it must have been split by its row byte representation
00344     * with MSBF-order
00345     *
00346     * @return the unspoiled float value
00347     */
00348     float Storage::readFloat() throw(std::invalid_argument)
00349     {
00350                 float value = 0;
00351                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
00352                 if (bigEndian_)
00353                 {
00354                         // network is big endian
00355                         p_value[0] = readChar();
00356                         p_value[1] = readChar();
00357                         p_value[2] = readChar();
00358                         p_value[3] = readChar();
00359                 } else {
00360                         // network is big endian
00361                         p_value[3] = readChar();
00362                         p_value[2] = readChar();
00363                         p_value[1] = readChar();
00364                         p_value[0] = readChar();
00365                 }
00366 
00367         return value;
00368 
00369     }
00370 
00371     // ----------------------------------------------------------------------
00372     void Storage::writeFloat( float value ) throw()
00373     {
00374                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
00375                 if (bigEndian_)
00376                 {
00377                         // network is big endian
00378                         writeChar(p_value[0]);
00379                         writeChar(p_value[1]);
00380                         writeChar(p_value[2]);
00381                         writeChar(p_value[3]);
00382                 } else {
00383                         // network is big endian
00384                         writeChar(p_value[3]);
00385                         writeChar(p_value[2]);
00386                         writeChar(p_value[1]);
00387                         writeChar(p_value[0]);
00388                 }
00389         }
00390         // ----------------------------------------------------------------------
00391         void Storage::writeDouble( double value ) throw ()
00392     {
00393                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
00394                 if (bigEndian_)
00395                 {
00396                         // network is big endian
00397                         for (int i=0; i<8; ++i)
00398             {
00399                                 writeChar(p_value[i]);
00400                         }
00401                 } else {
00402                         // network is big endian
00403                         for (int i=7; i>=0; --i)
00404                     {
00405                                 writeChar(p_value[i]);
00406                         }
00407                 }
00408         }
00409 
00410         // ----------------------------------------------------------------------
00411         double Storage::readDouble( ) throw (std::invalid_argument)
00412     {
00413                 double value = 0;
00414                 unsigned char *p_value = reinterpret_cast<unsigned char*>(&value);
00415                 if (bigEndian_)
00416                 {
00417                         // network is big endian
00418                         for (int i=0; i<8; ++i)
00419                 {
00420                                 p_value[i] = readChar();
00421                         }
00422                 } else {
00423                         // network is big endian
00424                         for (int i=7; i>=0; --i) {
00425                                 p_value[i] = readChar();
00426                         }
00427                 }
00428                 return value;
00429         }
00430 
00431         // ----------------------------------------------------------------------
00432 
00433         void Storage::writePacket(unsigned char* packet, int length)
00434         {
00435             store.reserve(length);
00436             for(int i = 0; i < length; ++i) store.push_back(packet[i]);
00437             //init();
00438         }
00439 
00440         // ----------------------------------------------------------------------
00441 
00442         void Storage::writeStorage(tcpip::Storage& store)
00443         {
00444             while (store.valid_pos())
00445                 writeChar( store.readChar() );
00446         }
00447 }
00448 
00449 #endif // BUILD_TCPIP
00450 
00451 /*-----------------------------------------------------------------------
00452  * Source  $Source: $
00453  * Version $Revision: 333 $
00454  * Date    $Date: 2009-02-19 13:30:30 +0100 (Thu, 19 Feb 2009) $
00455  *-----------------------------------------------------------------------
00456  * $Log: $
00457  *-----------------------------------------------------------------------*/

Generated on Wed May 5 00:06:36 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6