Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 using namespace std;
00020
00021 #include "ibrdtn/data/SDNV.h"
00022 #include "ibrdtn/data/Exceptions.h"
00023 #include <cstdlib>
00024 #include <cstring>
00025
00026 namespace dtn
00027 {
00028 namespace data
00029 {
00030
00031 SDNV::SDNV(const u_int64_t value) : _value(value)
00032 {}
00033
00034 SDNV::SDNV() : _value(0)
00035 {}
00036
00037 size_t SDNV::getLength() const
00038 {
00039 return getLength(_value);
00040 }
00041
00042 size_t SDNV::getLength(const u_int64_t &value)
00043 {
00044 return encoding_len(value);
00045 }
00046
00047 size_t SDNV::getLength(const unsigned char *data)
00048 {
00049 return len(data);
00050 }
00051
00052 u_int64_t SDNV::getValue() const
00053 {
00054 return _value;
00055 }
00056
00057 size_t SDNV::decode(const char *data, const size_t len)
00058 {
00059 return decode((unsigned char*)data, len, &_value);
00060 }
00061
00062 size_t SDNV::encode(char *data, const size_t len) const
00063 {
00064 return encode(_value, (unsigned char*)data, len);
00065 }
00066
00067 size_t SDNV::operator=(const size_t &value)
00068 {
00069 _value = value;
00070 return _value;
00071 }
00072
00073 bool SDNV::operator==(const SDNV &value) const
00074 {
00075 return (_value == value._value);
00076 }
00077
00078 bool SDNV::operator!=(const SDNV &value) const
00079 {
00080 return (_value != value._value);
00081 }
00082
00083 SDNV SDNV::operator+(const SDNV &value)
00084 {
00085 return SDNV(value.getValue() + getValue());
00086 }
00087
00088 SDNV& SDNV::operator+=(const SDNV &value)
00089 {
00090 _value += value._value;
00091 return (*this);
00092 }
00093
00094 SDNV SDNV::operator-(const SDNV &value)
00095 {
00096 return SDNV(value.getValue() - getValue());
00097 }
00098
00099 SDNV& SDNV::operator-=(const SDNV &value)
00100 {
00101 _value -= value._value;
00102 return (*this);
00103 }
00104
00105 bool SDNV::operator&(const size_t &value) const
00106 {
00107 return (_value & value);
00108 }
00109
00110 std::ostream &operator<<(std::ostream &stream, const dtn::data::SDNV &obj)
00111 {
00112 size_t len = obj.getLength();
00113 char* data = (char*)calloc(len, sizeof(char));
00114 obj.encode(data, len);
00115 stream.write(data, len);
00116 free(data);
00117
00118 return stream;
00119 }
00120
00121 std::istream &operator>>(std::istream &stream, dtn::data::SDNV &obj)
00122 {
00123 char sdnv[dtn::data::SDNV::MAX_LENGTH];
00124 char *sdnv_buf = sdnv;
00125 size_t sdnv_length = 0;
00126
00127 stream.read(sdnv_buf, sizeof(char));
00128 sdnv_length++;
00129
00130 while ( *sdnv_buf & 0x80)
00131 {
00132 sdnv_buf++;
00133 stream.read(sdnv_buf, sizeof(char));
00134 sdnv_length++;
00135 }
00136
00137 dtn::data::SDNV::decode(sdnv, sdnv_length, &obj._value);
00138
00139 return stream;
00140 }
00141
00147 int SDNV::encode(float val_f, u_char* bp, size_t len){
00148
00149 u_int32_t val_i;
00150 memcpy(&val_i, &val_f, sizeof(u_int32_t));
00151
00152 return encode((u_int64_t)val_i, bp, len);
00153 }
00154
00160 int SDNV::encode(u_int64_t val, u_char* bp, size_t len){
00161 u_char* start = bp;
00162
00163
00164 size_t val_len = 0;
00165 u_int64_t tmp = val;
00166
00167 do {
00168 tmp = tmp >> 7;
00169 val_len++;
00170 } while (tmp != 0);
00171
00172 if (!(val_len > 0)) throw InvalidDataException("ERROR(SDNV): !(val_len > 0)");
00173 if (!(val_len <= MAX_LENGTH)) throw InvalidDataException("ERROR(SDNV): !(val_len <= MAX_LENGTH)");
00174
00175 if (len < val_len) {
00176 return -1;
00177 }
00178
00179
00180 bp += val_len;
00181 u_char high_bit = 0;
00182 do {
00183 --bp;
00184 *bp = (u_char)(high_bit | (val & 0x7f));
00185 high_bit = (1 << 7);
00186 val = val >> 7;
00187 } while (val != 0);
00188
00189 if (!(bp == start)) throw InvalidDataException("ERROR(SDNV): !(bp == start)");
00190
00191 return val_len;
00192 }
00193
00194
00198 size_t SDNV::encoding_len(u_int64_t val){
00199 u_char buf[16];
00200 int ret = encode(val, buf, sizeof(buf));
00201 if (!(ret != -1 && ret != 0)) throw InvalidDataException("ERROR(SDNV): !(ret != -1 && ret != 0)");
00202 return ret;
00203 }
00204
00208 size_t SDNV::encoding_len(float val_f){
00209
00210 u_int32_t val_i;
00211 memcpy(&val_i, &val_f, sizeof(u_int32_t));
00212
00213 return encoding_len(val_i);
00214 }
00215
00222 int SDNV::decode(const u_char* bp, size_t len, u_int64_t* val){
00223 const u_char* start = bp;
00224
00225 if (!val) {
00226 throw InvalidDataException();
00227 }
00228
00229
00230
00231 size_t val_len = 0;
00232 *val = 0;
00233 do {
00234 if (len == 0)
00235 return -1;
00236
00237 *val = (*val << 7) | (*bp & 0x7f);
00238 ++val_len;
00239
00240 if ((*bp & (1 << 7)) == 0)
00241 break;
00242
00243 ++bp;
00244 --len;
00245 } while (1);
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 if ((val_len > MAX_LENGTH) || ((val_len == MAX_LENGTH) && (*start != 0x81))){
00256 throw InvalidDataException("ERROR(SDNV): overflow value in sdnv");
00257 }
00258
00259 return val_len;
00260 }
00261
00268 int SDNV::decode(const u_char* bp, size_t len, u_int32_t* val){
00269 u_int64_t lval;
00270 int ret = decode(bp, len, &lval);
00271
00272 if (lval > 0xffffffffLL) {
00273 throw InvalidDataException();
00274 }
00275
00276 *val = (u_int32_t)lval;
00277
00278 return ret;
00279 }
00280
00287 int SDNV::decode(const u_char* bp, size_t len, u_int16_t* val){
00288 u_int64_t lval;
00289 int ret = decode(bp, len, &lval);
00290
00291 if (lval > 0xffffffffLL) {
00292 throw InvalidDataException();
00293 }
00294
00295 *val = (u_int16_t)lval;
00296
00297 return ret;
00298 }
00299
00306 int SDNV::decode(const u_char* bp, size_t len, float* val){
00307 u_int64_t lval;
00308 int ret = decode(bp, len, &lval);
00309
00310 if (lval > 0xffffffffLL) {
00311 throw InvalidDataException();
00312 }
00313
00314 float fval;
00315 u_int32_t ival = (u_int32_t)lval;
00316 memcpy(&fval, &ival, sizeof(u_int32_t));
00317
00318 *val = fval;
00319
00320 return ret;
00321 }
00322
00327 size_t SDNV::len(const u_char* bp){
00328 size_t val_len = 1;
00329
00330 for ( ; *bp++ & 0x80; ++val_len )
00331 ;
00332 return val_len;
00333 }
00334 }
00335 }