IBR-DTNSuite 0.6

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 lastPos = data.find_first_not_of(token, 0);
00046                         // Find first "non-delimiter".
00047                         string::size_type pos     = data.find_first_of(token, lastPos);
00048 
00049                         while (string::npos != pos || string::npos != lastPos)
00050                         {
00051                                 // Found a token, add it to the vector.
00052                                 value = data.substr(lastPos, pos - lastPos);
00053                                 l.push_back(value);
00054                                 // Skip delimiters.  Note the "not_of"
00055                                 lastPos = data.find_first_not_of(token, pos);
00056                                 // Find next "non-delimiter"
00057                                 pos = data.find_first_of(token, lastPos);
00058 
00059                                 // if maximum reached
00060                                 if (l.size() >= max)
00061                                 {
00062                                         // add the remaining part to the vector as last element
00063                                         l.push_back(data.substr(lastPos, data.length() - lastPos));
00064 
00065                                         // and break the search loop
00066                                         break;
00067                                 }
00068                         }
00069 
00070                         return l;
00071                 }
00072 
00076                  double Utils::distance(double lat1, double lon1, double lat2, double lon2)
00077                  {
00078                         const double r = 6371; //km
00079 
00080                         double dLat = toRad( (lat2-lat1) );
00081                         double dLon = toRad( (lon2-lon1) );
00082 
00083                         double a =      sin(dLat/2) * sin(dLat/2) +
00084                                                 cos(toRad(lat1)) * cos(toRad(lat2)) *
00085                                                 sin(dLon/2) * sin(dLon/2);
00086                         double c = 2 * atan2(sqrt(a), sqrt(1-a));
00087                         return r * c;
00088                  }
00089 
00090                  const double Utils::pi = 3.14159;
00091 
00092                  double Utils::toRad(double value)
00093                  {
00094                         return value * pi / 180;
00095                  }
00096 
00097                 void Utils::encapsule(dtn::data::Bundle &capsule, const std::list<dtn::data::Bundle> &bundles)
00098                 {
00099                         bool custody = false;
00100                         size_t exp_time = 0;
00101 
00102                         try {
00103                                 const dtn::data::PayloadBlock &payload = capsule.getBlock<dtn::data::PayloadBlock>();
00104 
00105                                 // get the stream object of the payload
00106                                 ibrcommon::BLOB::Reference ref = payload.getBLOB();
00107 
00108                                 // clear the hole payload
00109                                 ref.iostream().clear();
00110 
00111                                 // encapsule the bundles into the BLOB
00112                                 Utils::encapsule(ref, bundles);
00113                         } catch (const dtn::data::Bundle::NoSuchBlockFoundException&) {
00114                                 ibrcommon::BLOB::Reference ref = ibrcommon::TmpFileBLOB::create();
00115 
00116                                 // encapsule the bundles into the BLOB
00117                                 Utils::encapsule(ref, bundles);
00118 
00119                                 // add a new payload block
00120                                 capsule.push_back(ref);
00121                         }
00122 
00123                         // get maximum lifetime
00124                         for (std::list<dtn::data::Bundle>::const_iterator iter = bundles.begin(); iter != bundles.end(); iter++)
00125                         {
00126                                 const dtn::data::Bundle &b = (*iter);
00127 
00128                                 // get the expiration time of this bundle
00129                                 size_t expt = dtn::utils::Clock::getExpireTime(b);
00130 
00131                                 // if this bundle expire later then use this lifetime
00132                                 if (expt > exp_time) exp_time = expt;
00133 
00134                                 // set custody to true if at least one bundle has custody requested
00135                                 if (b.get(dtn::data::PrimaryBlock::CUSTODY_REQUESTED)) custody = true;
00136                         }
00137 
00138                         // set the bundle flags
00139                         capsule.set(dtn::data::PrimaryBlock::CUSTODY_REQUESTED, custody);
00140 
00141                         // set the new lifetime
00142                         capsule._lifetime = exp_time - capsule._timestamp;
00143                 }
00144 
00145                 void Utils::encapsule(ibrcommon::BLOB::Reference &ref, const std::list<dtn::data::Bundle> &bundles)
00146                 {
00147                         ibrcommon::BLOB::iostream stream = ref.iostream();
00148 
00149                         // the number of encapsulated bundles
00150                         dtn::data::SDNV elements(bundles.size());
00151                         (*stream) << elements;
00152 
00153                         // create a serializer
00154                         dtn::data::DefaultSerializer serializer(*stream);
00155 
00156                         // write bundle offsets
00157                         std::list<dtn::data::Bundle>::const_iterator iter = bundles.begin();
00158 
00159                         for (size_t i = 0; i < (bundles.size() - 1); i++, iter++)
00160                         {
00161                                 const dtn::data::Bundle &b = (*iter);
00162                                 (*stream) << dtn::data::SDNV(serializer.getLength(b));
00163                         }
00164 
00165                         // serialize all bundles
00166                         for (std::list<dtn::data::Bundle>::const_iterator iter = bundles.begin(); iter != bundles.end(); iter++)
00167                         {
00168                                 serializer << (*iter);
00169                         }
00170                 }
00171 
00172                 void Utils::decapsule(const dtn::data::Bundle &capsule, std::list<dtn::data::Bundle> &bundles)
00173                 {
00174                         try {
00175                                 const dtn::data::PayloadBlock &payload = capsule.getBlock<dtn::data::PayloadBlock>();
00176                                 ibrcommon::BLOB::iostream stream = payload.getBLOB().iostream();
00177 
00178                                 // read the number of bundles
00179                                 dtn::data::SDNV nob; (*stream) >> nob;
00180 
00181                                 // read all offsets
00182                                 for (size_t i = 0; i < (nob.getValue() - 1); i++)
00183                                 {
00184                                         dtn::data::SDNV offset; (*stream) >> offset;
00185                                 }
00186 
00187                                 // create a deserializer for all bundles
00188                                 dtn::data::DefaultDeserializer deserializer(*stream);
00189                                 dtn::data::Bundle b;
00190 
00191                                 try {
00192                                         // read all bundles
00193                                         for (size_t i = 0; i < nob.getValue(); i++)
00194                                         {
00195                                                 // deserialize the next bundle
00196                                                 deserializer >> b;
00197 
00198                                                 // add the bundle to the list
00199                                                 bundles.push_back(b);
00200                                         }
00201                                 }
00202                                 catch (const dtn::InvalidDataException &ex) { };
00203                         } catch (const dtn::data::Bundle::NoSuchBlockFoundException&) { };
00204                 }
00205         }
00206 }