|
IBR-DTNSuite 0.6
|
00001 /* 00002 * Copyright 2005-2006 Intel Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 * 00016 * THIS FILE BASES ON DTN_2.4.0/SERVLIB/BUNDLING/SDNV.CC 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 // Convert the float to an int and call the encoding_len(int) function 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 //Figure out how many bytes we need for the encoding. 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 // Make sure we have enough buffer space. 00175 if (len < val_len) { 00176 return -1; 00177 } 00178 00179 // Now advance bp to the last byte and fill it in backwards with the value bytes. 00180 bp += val_len; 00181 u_char high_bit = 0; // for the last octet 00182 do { 00183 --bp; 00184 *bp = (u_char)(high_bit | (val & 0x7f)); 00185 high_bit = (1 << 7); // for all but the last octet 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 // Convert the float to an int and call the encoding_len(int) function 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 // Zero out the existing value, then shift in the bytes of the 00230 // encoding one by one until we hit a byte that has a zero high-order bit. 00231 size_t val_len = 0; 00232 *val = 0; 00233 do { 00234 if (len == 0) 00235 return -1; // buffer too short 00236 00237 *val = (*val << 7) | (*bp & 0x7f); 00238 ++val_len; 00239 00240 if ((*bp & (1 << 7)) == 0) 00241 break; // all done; 00242 00243 ++bp; 00244 --len; 00245 } while (1); 00246 00247 00248 // Since the spec allows for infinite length values but this 00249 // implementation only handles up to 64 bits, check for overflow. 00250 // Note that the only supportable 10 byte SDNV must store exactly 00251 // one bit in the first byte of the encoding (i.e. the 64'th bit 00252 // of the original value). 00253 // This is OK because a spec update says that behavior 00254 // is undefined for values > 64 bits. 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 }