IBR-DTNSuite  0.8
ibrdtn/ibrdtn/utils/Utils.cpp
Go to the documentation of this file.
00001 #include "ibrdtn/utils/Utils.h"
00002 #include "ibrcommon/data/BLOB.h"
00003 #include "ibrdtn/data/Exceptions.h"
00004 #include "ibrdtn/data/PayloadBlock.h"
00005 #include "ibrdtn/utils/Clock.h"
00006 
00007 #include <math.h>
00008 
00009 namespace dtn
00010 {
00011         namespace utils
00012         {
00013                 void Utils::rtrim(std::string &str)
00014                 {
00015                         // trim trailing spaces
00016                         size_t endpos = str.find_last_not_of(" \t");
00017                         if( string::npos != endpos )
00018                         {
00019                                 str = str.substr( 0, endpos+1 );
00020                         }
00021                 }
00022 
00023                 void Utils::ltrim(std::string &str)
00024                 {
00025                         // trim leading spaces
00026                         size_t startpos = str.find_first_not_of(" \t");
00027                         if( string::npos != startpos )
00028                         {
00029                                 str = str.substr( startpos );
00030                         }
00031                 }
00032 
00033                 void Utils::trim(std::string &str)
00034                 {
00035                         ltrim(str);
00036                         rtrim(str);
00037                 }
00038 
00039                 vector<string> Utils::tokenize(string token, string data, size_t max)
00040                 {
00041                         vector<string> l;
00042                         string value;
00043 
00044                         // Skip delimiters at beginning.
00045                         string::size_type pos = data.find_first_not_of(token, 0);
00046 
00047                         while (pos != string::npos)
00048                         {
00049                                 // Find first "non-delimiter".
00050                                 string::size_type tokenPos = data.find_first_of(token, pos);
00051 
00052                                 // Found a token, add it to the vector.
00053                                 if(tokenPos == string::npos){
00054                                         value = data.substr(pos);
00055                                         l.push_back(value);
00056                                         break;
00057                                 } else {
00058                                         value = data.substr(pos, tokenPos - pos);
00059                                         l.push_back(value);
00060                                 }
00061                                 // Skip delimiters.  Note the "not_of"
00062                                 pos = data.find_first_not_of(token, tokenPos);
00063                                 // Find next "non-delimiter"
00064                                 tokenPos = data.find_first_of(token, pos);
00065 
00066                                 // if maximum reached
00067                                 if (l.size() >= max && pos != string::npos)
00068                                 {
00069                                         // add the remaining part to the vector as last element
00070                                         l.push_back(data.substr(pos, data.length() - pos));
00071 
00072                                         // and break the search loop
00073                                         break;
00074                                 }
00075                         }
00076 
00077                         return l;
00078                 }
00079 
00083                  double Utils::distance(double lat1, double lon1, double lat2, double lon2)
00084                  {
00085                         const double r = 6371; //km
00086 
00087                         double dLat = toRad( (lat2-lat1) );
00088                         double dLon = toRad( (lon2-lon1) );
00089 
00090                         double a =      sin(dLat/2) * sin(dLat/2) +
00091                                                 cos(toRad(lat1)) * cos(toRad(lat2)) *
00092                                                 sin(dLon/2) * sin(dLon/2);
00093                         double c = 2 * atan2(sqrt(a), sqrt(1-a));
00094                         return r * c;
00095                  }
00096 
00097                  const double Utils::pi = 3.14159;
00098 
00099                  double Utils::toRad(double value)
00100                  {
00101                         return value * pi / 180;
00102                  }
00103 
00104                 void Utils::encapsule(dtn::data::Bundle &capsule, const std::list<dtn::data::Bundle> &bundles)
00105                 {
00106                         bool custody = false;
00107                         size_t exp_time = 0;
00108 
00109                         try {
00110                                 const dtn::data::PayloadBlock &payload = capsule.getBlock<dtn::data::PayloadBlock>();
00111 
00112                                 // get the stream object of the payload
00113                                 ibrcommon::BLOB::Reference ref = payload.getBLOB();
00114 
00115                                 // clear the hole payload
00116                                 ref.iostream().clear();
00117 
00118                                 // encapsule the bundles into the BLOB
00119                                 Utils::encapsule(ref, bundles);
00120                         } catch (const dtn::data::Bundle::NoSuchBlockFoundException&) {
00121                                 ibrcommon::BLOB::Reference ref = ibrcommon::BLOB::create();
00122 
00123                                 // encapsule the bundles into the BLOB
00124                                 Utils::encapsule(ref, bundles);
00125 
00126                                 // add a new payload block
00127                                 capsule.push_back(ref);
00128                         }
00129 
00130                         // get maximum lifetime
00131                         for (std::list<dtn::data::Bundle>::const_iterator iter = bundles.begin(); iter != bundles.end(); iter++)
00132                         {
00133                                 const dtn::data::Bundle &b = (*iter);
00134 
00135                                 // get the expiration time of this bundle
00136                                 size_t expt = dtn::utils::Clock::getExpireTime(b);
00137 
00138                                 // if this bundle expire later then use this lifetime
00139                                 if (expt > exp_time) exp_time = expt;
00140 
00141                                 // set custody to true if at least one bundle has custody requested
00142                                 if (b.get(dtn::data::PrimaryBlock::CUSTODY_REQUESTED)) custody = true;
00143                         }
00144 
00145                         // set the bundle flags
00146                         capsule.set(dtn::data::PrimaryBlock::CUSTODY_REQUESTED, custody);
00147 
00148                         // set the new lifetime
00149                         capsule._lifetime = exp_time - capsule._timestamp;
00150                 }
00151 
00152                 void Utils::encapsule(ibrcommon::BLOB::Reference &ref, const std::list<dtn::data::Bundle> &bundles)
00153                 {
00154                         ibrcommon::BLOB::iostream stream = ref.iostream();
00155 
00156                         // the number of encapsulated bundles
00157                         dtn::data::SDNV elements(bundles.size());
00158                         (*stream) << elements;
00159 
00160                         // create a serializer
00161                         dtn::data::DefaultSerializer serializer(*stream);
00162 
00163                         // write bundle offsets
00164                         std::list<dtn::data::Bundle>::const_iterator iter = bundles.begin();
00165 
00166                         for (size_t i = 0; i < (bundles.size() - 1); i++, iter++)
00167                         {
00168                                 const dtn::data::Bundle &b = (*iter);
00169                                 (*stream) << dtn::data::SDNV(serializer.getLength(b));
00170                         }
00171 
00172                         // serialize all bundles
00173                         for (std::list<dtn::data::Bundle>::const_iterator iter = bundles.begin(); iter != bundles.end(); iter++)
00174                         {
00175                                 serializer << (*iter);
00176                         }
00177                 }
00178 
00179                 void Utils::decapsule(const dtn::data::Bundle &capsule, std::list<dtn::data::Bundle> &bundles)
00180                 {
00181                         try {
00182                                 const dtn::data::PayloadBlock &payload = capsule.getBlock<dtn::data::PayloadBlock>();
00183                                 ibrcommon::BLOB::iostream stream = payload.getBLOB().iostream();
00184 
00185                                 // read the number of bundles
00186                                 dtn::data::SDNV nob; (*stream) >> nob;
00187 
00188                                 // read all offsets
00189                                 for (size_t i = 0; i < (nob.getValue() - 1); i++)
00190                                 {
00191                                         dtn::data::SDNV offset; (*stream) >> offset;
00192                                 }
00193 
00194                                 // create a deserializer for all bundles
00195                                 dtn::data::DefaultDeserializer deserializer(*stream);
00196                                 dtn::data::Bundle b;
00197 
00198                                 try {
00199                                         // read all bundles
00200                                         for (size_t i = 0; i < nob.getValue(); i++)
00201                                         {
00202                                                 // deserialize the next bundle
00203                                                 deserializer >> b;
00204 
00205                                                 // add the bundle to the list
00206                                                 bundles.push_back(b);
00207                                         }
00208                                 }
00209                                 catch (const dtn::InvalidDataException &ex) { };
00210                         } catch (const dtn::data::Bundle::NoSuchBlockFoundException&) { };
00211                 }
00212         }
00213 }