IBR-DTN  1.0.0
SDNV.h
Go to the documentation of this file.
1 /*
2  * SDNV.h
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  * THIS FILE BASES ON DTN_2.4.0/SERVLIB/BUNDLING/SDNV.H
21  */
22 
23 #include <ibrcommon/Exceptions.h>
24 #include <ibrdtn/data/Exceptions.h>
25 #include <ibrdtn/utils/Random.h>
26 
27 #include <sstream>
28 #include <sys/types.h>
29 #include <iostream>
30 #include <stdio.h>
31 #include <stdint.h>
32 #include <limits>
33 #include <cstdlib>
34 
35 #ifndef _SDNV_H_
36 #define _SDNV_H_
37 
56 namespace dtn
57 {
58  namespace data
59  {
61  {
62  public:
63  ValueOutOfRangeException(const std::string &what = "The value is out of range.") throw() : dtn::InvalidDataException(what)
64  {
65  };
66  };
67 
68  template<class E>
69  class SDNV
70  {
71  public:
76  static const size_t MAX_LENGTH = 10;
77 
82  SDNV(const E value) : _value(value) {
83  }
84 
85  SDNV() : _value(0) {
86  }
87 
92  ~SDNV() {
93  }
94 
99  size_t getLength() const
100  {
101  size_t val_len = 0;
102  E tmp = _value;
103 
104  do {
105  tmp = tmp >> 7;
106  val_len++;
107  } while (tmp != 0);
108 
109  return val_len;
110  }
111 
112  template<typename T>
113  T get() const {
114  return static_cast<T>(_value);
115  }
116 
117  const E& get() const {
118  return _value;
119  }
120 
121  const SDNV& operator=(const E value) {
122  _value = value;
123  return (*this);
124  }
125 
126  bool operator==(const E value) const
127  {
128  return (value == _value);
129  }
130 
131  bool operator==(const SDNV<E> &value) const
132  {
133  return (value._value == _value);
134  }
135 
136  bool operator!=(const E value) const
137  {
138  return (value != _value);
139  }
140 
141  bool operator!=(const SDNV<E> &value) const
142  {
143  return (value._value != _value);
144  }
145 
146  SDNV<E> operator+(const E value)
147  {
148  E result = _value + value;
149  return SDNV<E>(result);
150  }
151 
152  SDNV<E> operator+(const SDNV<E> &value)
153  {
154  E result = _value + value._value;
155  return SDNV<E>(result);
156  }
157 
158  friend
159  SDNV<E> operator+(const SDNV<E> &left, const SDNV<E> &right)
160  {
161  SDNV<E> ret(left);
162  ret += right;
163  return ret;
164  }
165 
166  friend
167  SDNV<E> operator+(const SDNV<E> &left, const E right)
168  {
169  SDNV<E> ret(left);
170  ret += right;
171  return ret;
172  }
173 
174  SDNV<E>& operator+=(const E value)
175  {
176  _value += value;
177  return (*this);
178  }
179 
180  SDNV<E>& operator+=(const SDNV<E> &value)
181  {
182  _value += value._value;
183  return (*this);
184  }
185 
186  SDNV<E>& operator++() // prefix
187  {
188  ++_value;
189  return (*this);
190  }
191 
192  SDNV<E> operator++(int) // postfix
193  {
194  SDNV<E> prev(*this);
195  ++_value;
196  return prev;
197  }
198 
199  SDNV<E> operator-(const E value)
200  {
201  E result = _value - value;
202  return SDNV<E>(result);
203  }
204 
205  SDNV<E> operator-(const SDNV<E> &value)
206  {
207  E result = _value - value._value;
208  return SDNV<E>(result);
209  }
210 
211  friend
212  SDNV<E> operator-(const SDNV<E> &left, const SDNV<E> &right)
213  {
214  SDNV<E> ret(left);
215  ret -= right;
216  return ret;
217  }
218 
219  friend
220  SDNV<E> operator-(const SDNV<E> &left, const E right)
221  {
222  SDNV<E> ret(left);
223  ret -= right;
224  return ret;
225  }
226 
227  SDNV<E>& operator-=(const E value)
228  {
229  _value -= value;
230  return (*this);
231  }
232 
233  SDNV<E>& operator-=(const SDNV<E> &value)
234  {
235  _value -= value._value;
236  return (*this);
237  }
238 
239  SDNV<E>& operator--() // prefix
240  {
241  --_value;
242  return (*this);
243  }
244 
245  SDNV<E> operator--(int) // postfix
246  {
247  SDNV<E> prev(*this);
248  --_value;
249  return prev;
250  }
251 
252  SDNV<E> operator/(const E value)
253  {
254  E result = _value / value;
255  return SDNV<E>(result);
256  }
257 
258  SDNV<E> operator/(const SDNV<E> &value)
259  {
260  E result = _value / value._value;
261  return SDNV<E>(result);
262  }
263 
264  friend
265  SDNV<E> operator/(const SDNV<E> &left, const SDNV<E> &right)
266  {
267  SDNV<E> ret(left);
268  ret /= right;
269  return ret;
270  }
271 
272  friend
273  SDNV<E> operator/(const SDNV<E> &left, const E right)
274  {
275  SDNV<E> ret(left);
276  ret /= right;
277  return ret;
278  }
279 
280  SDNV<E>& operator/=(const E value)
281  {
282  _value /= value;
283  return (*this);
284  }
285 
286  SDNV<E>& operator/=(const SDNV<E> &value)
287  {
288  _value /= value._value;
289  return (*this);
290  }
291 
292  SDNV<E> operator*(const E value)
293  {
294  E result = _value * value;
295  return SDNV<E>(result);
296  }
297 
298  SDNV<E> operator*(const SDNV<E> &value)
299  {
300  E result = _value * value._value;
301  return SDNV<E>(result);
302  }
303 
304  friend
305  SDNV<E> operator*(const SDNV<E> &left, const SDNV<E> &right)
306  {
307  SDNV<E> ret(left);
308  ret *= right;
309  return ret;
310  }
311 
312  friend
313  SDNV<E> operator*(const SDNV<E> &left, const E right)
314  {
315  SDNV<E> ret(left);
316  ret *= right;
317  return ret;
318  }
319 
320  SDNV<E>& operator*=(const E value)
321  {
322  _value *= value;
323  return (*this);
324  }
325 
326  SDNV<E>& operator*=(const SDNV<E> &value)
327  {
328  _value *= value._value;
329  return (*this);
330  }
331 
332  bool operator&(const SDNV<E> &value) const
333  {
334  return (value._value & _value);
335  }
336 
337  bool operator|(const SDNV<E> &value) const
338  {
339  return (value._value | _value);
340  }
341 
342  SDNV<E>& operator&=(const SDNV<E> &value)
343  {
344  _value &= value._value;
345  return (*this);
346  }
347 
348  SDNV<E>& operator|=(const SDNV<E> &value)
349  {
350  _value |= value._value;
351  return (*this);
352  }
353 
354  bool operator<(const E value) const
355  {
356  return (_value < value);
357  }
358 
359  bool operator<=(const E value) const
360  {
361  return (_value <= value);
362  }
363 
364  bool operator>(const E value) const
365  {
366  return (_value > value);
367  }
368 
369  bool operator>=(const E value) const
370  {
371  return (_value >= value);
372  }
373 
374  bool operator<(const SDNV<E> &value) const
375  {
376  return (_value < value._value);
377  }
378 
379  bool operator<=(const SDNV<E> &value) const
380  {
381  return (_value <= value._value);
382  }
383 
384  bool operator>(const SDNV<E> &value) const
385  {
386  return (_value > value._value);
387  }
388 
389  bool operator>=(const SDNV<E> &value) const
390  {
391  return (_value >= value._value);
392  }
393 
394  static SDNV<E> max()
395  {
396  return std::numeric_limits<E>::max();
397  }
398 
399  template <typename V>
401  {
402  E val = (E)dtn::utils::Random::gen_number();
403  (*this) = static_cast<E>(val);
404  trim<V>();
405  return (*this);
406  }
407 
408  template <typename V>
409  void trim()
410  {
411  (*this) &= std::numeric_limits<V>::max();
412  }
413 
414  std::string toString() const {
415  std::stringstream ss;
416  ss << _value;
417  return ss.str();
418  }
419 
420  void fromString(const std::string &data) {
421  std::stringstream ss; ss.str(data);
422  ss >> _value;
423  }
424 
425  void read(std::istream &stream) {
426  stream >> _value;
427  }
428 
429  void encode(std::ostream &stream) const
430  {
431  unsigned char buffer[10];
432  unsigned char *bp = &buffer[0];
433  uint64_t val = _value;
434 
435  const size_t val_len = getLength();
436 
437  if (!(val_len > 0)) throw ValueOutOfRangeException("ERROR(SDNV): !(val_len > 0)");
438  if (!(val_len <= SDNV::MAX_LENGTH)) throw ValueOutOfRangeException("ERROR(SDNV): !(val_len <= MAX_LENGTH)");
439 
440  // Now advance bp to the last byte and fill it in backwards with the value bytes.
441  bp += val_len;
442  unsigned char high_bit = 0; // for the last octet
443  do {
444  --bp;
445  *bp = (unsigned char)(high_bit | (val & 0x7f));
446  high_bit = (1 << 7); // for all but the last octet
447  val = val >> 7;
448  } while (val != 0);
449 
450  if (!(bp == &buffer[0])) throw ValueOutOfRangeException("ERROR(SDNV): !(bp == buffer)");
451 
452  // write encoded value to the stream
453  stream.write((const char*)&buffer[0], val_len);
454  }
455 
456  void decode(std::istream &stream)
457  {
458  size_t val_len = 0;
459  unsigned char bp = 0;
460  unsigned char start = 0;
461 
462  int carry = 0;
463 
464  _value = 0;
465  do {
466  stream.get((char&)bp);
467 
468  _value = (_value << 7) | (bp & 0x7f);
469  ++val_len;
470 
471  if ((bp & (1 << 7)) == 0)
472  break; // all done;
473 
474  // check if the value fits into sizeof(E)
475  if ((val_len % 8) == 0) ++carry;
476 
477  if ((sizeof(E) + carry) < val_len)
478  throw ValueOutOfRangeException("ERROR(SDNV): overflow value in sdnv");
479 
480  if (start == 0) start = bp;
481  } while (1);
482 
483  if ((val_len > SDNV::MAX_LENGTH) || ((val_len == SDNV::MAX_LENGTH) && (start != 0x81)))
484  throw ValueOutOfRangeException("ERROR(SDNV): overflow value in sdnv");
485  }
486 
487  private:
488  friend
489  std::ostream &operator<<(std::ostream &stream, const dtn::data::SDNV<E> &obj)
490  {
491  obj.encode(stream);
492  return stream;
493  }
494 
495  friend
496  std::istream &operator>>(std::istream &stream, dtn::data::SDNV<E> &obj)
497  {
498  obj.decode(stream);
499  return stream;
500  }
501 
502  E _value;
503  };
504  }
505 }
506 
507 #endif /* _SDNV_H_ */
void decode(std::istream &stream)
Definition: SDNV.h:456
SDNV< E > operator*(const E value)
Definition: SDNV.h:292
bool operator>=(const E value) const
Definition: SDNV.h:369
SDNV< E > operator+(const E value)
Definition: SDNV.h:146
friend SDNV< E > operator/(const SDNV< E > &left, const E right)
Definition: SDNV.h:273
SDNV< E > & operator|=(const SDNV< E > &value)
Definition: SDNV.h:348
SDNV< E > & operator-=(const SDNV< E > &value)
Definition: SDNV.h:233
bool operator!=(const SDNV< E > &value) const
Definition: SDNV.h:141
SDNV< E > operator*(const SDNV< E > &value)
Definition: SDNV.h:298
SDNV< E > & operator+=(const E value)
Definition: SDNV.h:174
const SDNV & operator=(const E value)
Definition: SDNV.h:121
SDNV< E > operator+(const SDNV< E > &value)
Definition: SDNV.h:152
void trim()
Definition: SDNV.h:409
SDNV(const E value)
Definition: SDNV.h:82
SDNV< E > & operator*=(const E value)
Definition: SDNV.h:320
SDNV< E > & operator--()
Definition: SDNV.h:239
bool operator|(const SDNV< E > &value) const
Definition: SDNV.h:337
size_t getLength() const
Definition: SDNV.h:99
bool operator!=(const E value) const
Definition: SDNV.h:136
SDNV< E > operator-(const SDNV< E > &value)
Definition: SDNV.h:205
friend SDNV< E > operator-(const SDNV< E > &left, const E right)
Definition: SDNV.h:220
static int gen_number()
Definition: Random.cpp:51
bool operator==(const E value) const
Definition: SDNV.h:126
static SDNV< E > max()
Definition: SDNV.h:394
std::string toString() const
Definition: SDNV.h:414
friend SDNV< E > operator/(const SDNV< E > &left, const SDNV< E > &right)
Definition: SDNV.h:265
friend SDNV< E > operator-(const SDNV< E > &left, const SDNV< E > &right)
Definition: SDNV.h:212
friend SDNV< E > operator+(const SDNV< E > &left, const SDNV< E > &right)
Definition: SDNV.h:159
SDNV< E > & operator&=(const SDNV< E > &value)
Definition: SDNV.h:342
friend SDNV< E > operator*(const SDNV< E > &left, const E right)
Definition: SDNV.h:313
SDNV< E > & random()
Definition: SDNV.h:400
friend std::istream & operator>>(std::istream &stream, dtn::data::SDNV< E > &obj)
Definition: SDNV.h:496
void read(std::istream &stream)
Definition: SDNV.h:425
ValueOutOfRangeException(const std::string &what="The value is out of range.")
Definition: SDNV.h:63
bool operator>(const E value) const
Definition: SDNV.h:364
SDNV< E > & operator*=(const SDNV< E > &value)
Definition: SDNV.h:326
bool operator<=(const E value) const
Definition: SDNV.h:359
friend SDNV< E > operator+(const SDNV< E > &left, const E right)
Definition: SDNV.h:167
void fromString(const std::string &data)
Definition: SDNV.h:420
bool operator>(const SDNV< E > &value) const
Definition: SDNV.h:384
SDNV< E > & operator-=(const E value)
Definition: SDNV.h:227
SDNV< E > & operator/=(const SDNV< E > &value)
Definition: SDNV.h:286
static const size_t MAX_LENGTH
Definition: SDNV.h:76
SDNV< E > & operator+=(const SDNV< E > &value)
Definition: SDNV.h:180
SDNV< E > operator/(const E value)
Definition: SDNV.h:252
SDNV< E > operator/(const SDNV< E > &value)
Definition: SDNV.h:258
friend SDNV< E > operator*(const SDNV< E > &left, const SDNV< E > &right)
Definition: SDNV.h:305
SDNV< E > & operator/=(const E value)
Definition: SDNV.h:280
bool operator==(const SDNV< E > &value) const
Definition: SDNV.h:131
bool operator<(const E value) const
Definition: SDNV.h:354
SDNV< E > operator++(int)
Definition: SDNV.h:192
SDNV< E > & operator++()
Definition: SDNV.h:186
SDNV< E > operator-(const E value)
Definition: SDNV.h:199
SDNV< E > operator--(int)
Definition: SDNV.h:245
bool operator&(const SDNV< E > &value) const
Definition: SDNV.h:332
bool operator>=(const SDNV< E > &value) const
Definition: SDNV.h:389
void encode(std::ostream &stream) const
Definition: SDNV.h:429