|
IBR-DTNSuite 0.6
|
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 }