IBR-DTNSuite  0.10
Utils.cpp
Go to the documentation of this file.
1 /*
2  * Utils.cpp
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #include "ibrdtn/utils/Utils.h"
23 #include "ibrcommon/data/BLOB.h"
24 #include "ibrdtn/data/Exceptions.h"
26 #include "ibrdtn/utils/Clock.h"
27 
28 #include <math.h>
29 
30 namespace dtn
31 {
32  namespace utils
33  {
34  void Utils::rtrim(std::string &str)
35  {
36  // trim trailing spaces
37  std::string::size_type endpos = str.find_last_not_of(" \t");
38  if( string::npos != endpos )
39  {
40  str = str.substr( 0, endpos+1 );
41  }
42  }
43 
44  void Utils::ltrim(std::string &str)
45  {
46  // trim leading spaces
47  std::string::size_type startpos = str.find_first_not_of(" \t");
48  if( string::npos != startpos )
49  {
50  str = str.substr( startpos );
51  }
52  }
53 
54  void Utils::trim(std::string &str)
55  {
56  ltrim(str);
57  rtrim(str);
58  }
59 
60  std::vector<std::string> Utils::tokenize(const std::string &token, const std::string &data, const std::string::size_type max)
61  {
62  std::vector<std::string> l;
63  std::string value;
64 
65  // Skip delimiters at beginning.
66  std::string::size_type pos = data.find_first_not_of(token, 0);
67 
68  std::string::size_type tokenPos = 0;
69 
70  while (pos != string::npos)
71  {
72  if (l.size() >= max)
73  {
74  // if maximum reached
75  tokenPos = std::string::npos;
76  }
77  else
78  {
79  // Find first "non-delimiter".
80  tokenPos = data.find_first_of(token, pos);
81  }
82 
83  if (tokenPos == std::string::npos) {
84  // No more tokens found, add last part to the vector.
85  value = data.substr(pos);
86  l.push_back(value);
87 
88  // exit the loop
89  break;
90  } else {
91  // Found a token, add it to the vector.
92  value = data.substr(pos, tokenPos - pos);
93  l.push_back(value);
94  }
95  // Skip delimiters. Note the "not_of"
96  pos = data.find_first_not_of(token, tokenPos);
97  }
98 
99  return l;
100  }
101 
105  double Utils::distance(double lat1, double lon1, double lat2, double lon2)
106  {
107  const double r = 6371; //km
108 
109  double dLat = toRad( (lat2-lat1) );
110  double dLon = toRad( (lon2-lon1) );
111 
112  double a = sin(dLat/2) * sin(dLat/2) +
113  cos(toRad(lat1)) * cos(toRad(lat2)) *
114  sin(dLon/2) * sin(dLon/2);
115  double c = 2 * atan2(sqrt(a), sqrt(1-a));
116  return r * c;
117  }
118 
119  const double Utils::pi = 3.14159;
120 
121  double Utils::toRad(double value)
122  {
123  return value * pi / 180;
124  }
125 
126  void Utils::encapsule(dtn::data::Bundle &capsule, const std::list<dtn::data::Bundle> &bundles)
127  {
128  bool custody = false;
129  dtn::data::Number exp_time = 0;
130 
131  try {
132  const dtn::data::PayloadBlock &payload = capsule.find<dtn::data::PayloadBlock>();
133 
134  // get the stream object of the payload
135  ibrcommon::BLOB::Reference ref = payload.getBLOB();
136 
137  // clear the hole payload
138  ref.iostream().clear();
139 
140  // encapsule the bundles into the BLOB
141  Utils::encapsule(ref, bundles);
144 
145  // encapsule the bundles into the BLOB
146  Utils::encapsule(ref, bundles);
147 
148  // add a new payload block
149  capsule.push_back(ref);
150  }
151 
152  // get maximum lifetime
153  for (std::list<dtn::data::Bundle>::const_iterator iter = bundles.begin(); iter != bundles.end(); ++iter)
154  {
155  const dtn::data::Bundle &b = (*iter);
156 
157  // get the expiration time of this bundle
159 
160  // if this bundle expire later then use this lifetime
161  if (expt > exp_time) exp_time = expt;
162 
163  // set custody to true if at least one bundle has custody requested
164  if (b.get(dtn::data::PrimaryBlock::CUSTODY_REQUESTED)) custody = true;
165  }
166 
167  // set the bundle flags
169 
170  // set the new lifetime
171  capsule.lifetime = exp_time - capsule.timestamp;
172  }
173 
174  void Utils::encapsule(ibrcommon::BLOB::Reference &ref, const std::list<dtn::data::Bundle> &bundles)
175  {
176  ibrcommon::BLOB::iostream stream = ref.iostream();
177 
178  // the number of encapsulated bundles
179  dtn::data::Number elements(bundles.size());
180  (*stream) << elements;
181 
182  // create a serializer
183  dtn::data::DefaultSerializer serializer(*stream);
184 
185  // write bundle offsets
186  std::list<dtn::data::Bundle>::const_iterator iter = bundles.begin();
187 
188  for (size_t i = 0; i < (bundles.size() - 1); i++, iter++)
189  {
190  const dtn::data::Bundle &b = (*iter);
191  (*stream) << dtn::data::Number(serializer.getLength(b));
192  }
193 
194  // serialize all bundles
195  for (std::list<dtn::data::Bundle>::const_iterator iter = bundles.begin(); iter != bundles.end(); ++iter)
196  {
197  serializer << (*iter);
198  }
199  }
200 
201  void Utils::decapsule(const dtn::data::Bundle &capsule, std::list<dtn::data::Bundle> &bundles)
202  {
203  try {
204  const dtn::data::PayloadBlock &payload = capsule.find<dtn::data::PayloadBlock>();
205  ibrcommon::BLOB::iostream stream = payload.getBLOB().iostream();
206 
207  // read the number of bundles
208  dtn::data::Number nob; (*stream) >> nob;
209 
210  // read all offsets
211  for (size_t i = 0; (nob - 1) > i; ++i)
212  {
213  dtn::data::Number offset; (*stream) >> offset;
214  }
215 
216  // create a deserializer for all bundles
217  dtn::data::DefaultDeserializer deserializer(*stream);
219 
220  try {
221  // read all bundles
222  for (size_t i = 0; nob > i; ++i)
223  {
224  // deserialize the next bundle
225  deserializer >> b;
226 
227  // add the bundle to the list
228  bundles.push_back(b);
229  }
230  }
231  catch (const dtn::InvalidDataException &ex) { };
233  }
234 
235  std::string Utils::toString(const dtn::data::Length &value)
236  {
237  std::stringstream ss;
238  ss << value;
239  return ss.str();
240  }
241  }
242 }