00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef BITINTEGER_H
00020 #define BITINTEGER_H
00021
00022 #include <typeinfo>
00023
00024 #include <bit/enums.h>
00025 #include <bit/utility.h>
00026 #include <bit/pointer.h>
00027 #include <bit/data.h>
00028
00029 namespace bit
00030 {
00031
00032 template <typename I> class Int;
00033
00034 class Integer
00035 {
00036 public:
00037
00038 typedef BitPointer<Integer> pointer;
00039
00040 Integer( ByteOrder bo=BYTEORDER_HOST ): byte_order(bo) { }
00041
00042 virtual ~Integer() { }
00043
00044 virtual Data as_data() const = 0;
00045
00046 virtual size_t size() const = 0;
00047
00048 virtual const void* voidptr() const = 0;
00049
00050 virtual pointer clone() const = 0;
00051
00057 virtual void set_value( const Data d ) = 0;
00058
00059 virtual void set_value( const void* mem, size_t size ) = 0;
00060
00066 virtual void set_value( const Data d, ByteOrder databo ) = 0;
00067
00068 template <typename T> operator T();
00069
00070 template <typename T> Integer& operator = ( T i );
00071
00072 virtual const std::type_info& int_type() = 0;
00073
00074 ByteOrder byte_order;
00075 };
00076
00077 template <typename I>
00078 class Int: public Integer {
00079 public:
00080
00081 typedef BitPointer< Int<I> > pointer;
00082
00083 Int(I v=0, ByteOrder bo=BYTEORDER_HOST): Integer(bo), value(v) { }
00084
00085 Int(ByteOrder bo): Integer(bo), value(0) { }
00086
00093 Int(const Data d, ByteOrder databo=BYTEORDER_HOST, ByteOrder bo=BYTEORDER_HOST): Integer(bo) {
00094 this->set_value(d, databo);
00095 }
00096
00097 static pointer create(I v=0, ByteOrder bo=BYTEORDER_HOST) { return pointer(new Int<I>(v,bo)); }
00098
00099 static pointer create(ByteOrder bo) { return pointer(new Int<I>(bo)); }
00100
00101 static pointer create(const Data d, ByteOrder databo=BYTEORDER_HOST, ByteOrder bo=BYTEORDER_HOST) {
00102 return pointer(new Int<I>(d,databo,bo));
00103 }
00104
00105 ~Int() { }
00106
00107 virtual Integer::pointer clone() const {
00108 pointer p = this->create(value, byte_order);
00109 return p;
00110 }
00111
00112 operator I() const { return this->host(); }
00113
00114 bool operator < ( I i ) const { return this->host() < i; }
00115 bool operator <= ( I i ) const { return this->host() <= i; }
00116 bool operator == ( I i ) const { return this->host() == i; }
00117 bool operator != ( I i ) const { return this->host() != i; }
00118 bool operator >= ( I i ) const { return this->host() >= i; }
00119 bool operator > ( I i ) const { return this->host() > i; }
00120
00121 Int<I>& operator = ( I i )
00122 {
00123 value = i;
00124 this->convert_value_from_host_to_type();
00125 return *this;
00126 }
00127
00128 Int<I> operator + ( I i ) const
00129 {
00130 this->convert_value_from_type_to_host();
00131 value += i;
00132 this->convert_value_from_host_to_type();
00133 return *this;
00134 }
00135
00136 Int<I> operator - ( I i ) const
00137 {
00138 this->convert_value_from_type_to_host();
00139 value -= i;
00140 this->convert_value_from_host_to_type();
00141 return *this;
00142 }
00143
00144 Int<I> operator * ( I i ) const
00145 {
00146 this->convert_value_from_type_to_host();
00147 value *= i;
00148 this->convert_value_from_host_to_type();
00149 return *this;
00150 }
00151
00152 Int<I> operator / ( I i ) const
00153 {
00154 this->convert_value_from_type_to_host();
00155 value /= i;
00156 this->convert_value_from_host_to_type();
00157 return *this;
00158 }
00159
00160 Int<I> operator % ( I i ) const
00161 {
00162 this->convert_value_from_type_to_host();
00163 value %= i;
00164 this->convert_value_from_host_to_type();
00165 return *this;
00166 }
00167
00168 Int<I>& operator += ( I i )
00169 {
00170 this->convert_value_from_type_to_host();
00171 value += i;
00172 this->convert_value_from_host_to_type();
00173 return *this;
00174 }
00175
00176 Int<I>& operator -= ( I i )
00177 {
00178 this->convert_value_from_type_to_host();
00179 value -= i;
00180 this->convert_value_from_host_to_type();
00181 return *this;
00182 }
00183
00184 Int<I>& operator *= ( I i )
00185 {
00186 this->convert_value_from_type_to_host();
00187 value *= i;
00188 this->convert_value_from_host_to_type();
00189 return *this;
00190 }
00191
00192 Int<I>& operator /= ( I i )
00193 {
00194 this->convert_value_from_type_to_host();
00195 value /= i;
00196 this->convert_value_from_host_to_type();
00197 return *this;
00198 }
00199
00200 Int<I>& operator %= ( I i )
00201 {
00202 this->convert_value_from_type_to_host();
00203 value %= i;
00204 this->convert_value_from_host_to_type();
00205 return *this;
00206 }
00207
00213 virtual void set_value( const Data d ) {
00214 if ( d.size() < sizeof(I) )
00215 throw;
00216
00217 memcpy( &value, d.data(), sizeof(I) );
00218 }
00219
00224 virtual void set_value( const void* mem, size_t size ) {
00225 if ( size < sizeof(I) )
00226 throw;
00227
00228 memcpy( &value, mem, sizeof(I) );
00229 }
00230
00236 virtual void set_value( const Data d, ByteOrder databo ) {
00237 if ( d.size() < sizeof(I) )
00238 throw;
00239
00240 memcpy( &value, d.data(), sizeof(I) );
00241
00242 switch ( byte_order ) {
00243 case BYTEORDER_HOST:
00244 switch ( databo ) {
00245 case BYTEORDER_HOST:
00246 break;
00247 case BYTEORDER_NETWORK:
00248 case BYTEORDER_BIG_ENDIAN:
00249 value = be_to_host(value);
00250 break;
00251 case BYTEORDER_LITTLE_ENDIAN:
00252 value = le_to_host(value);
00253 break;
00254 }
00255 break;
00256 case BYTEORDER_NETWORK:
00257 case BYTEORDER_BIG_ENDIAN:
00258 switch ( databo ) {
00259 case BYTEORDER_HOST:
00260 value = host_to_net(value);
00261 break;
00262 case BYTEORDER_NETWORK:
00263 case BYTEORDER_BIG_ENDIAN:
00264 break;
00265 case BYTEORDER_LITTLE_ENDIAN:
00266 value = le_to_net(value);
00267 break;
00268 }
00269 break;
00270 case BYTEORDER_LITTLE_ENDIAN:
00271 switch ( databo ) {
00272 case BYTEORDER_HOST:
00273 value = host_to_le(value);
00274 break;
00275 case BYTEORDER_NETWORK:
00276 case BYTEORDER_BIG_ENDIAN:
00277 value = net_to_le(value);
00278 break;
00279 case BYTEORDER_LITTLE_ENDIAN:
00280 break;
00281 }
00282 break;
00283 }
00284 }
00285
00286 virtual Data as_data() const
00287 {
00288 Data d( sizeof(I) );
00289 memcpy( d.data(), &value, sizeof(I) );
00290 return d;
00291 }
00292
00293 virtual size_t size() const { return sizeof(I); }
00294
00295 virtual const void* voidptr() const { return &value; }
00296
00297 virtual const std::type_info& int_type() { return typeid(I); }
00298
00299 I host() const {
00300 switch ( byte_order )
00301 {
00302 case BYTEORDER_HOST:
00303 return value;
00304 case BYTEORDER_NETWORK:
00305 case BYTEORDER_BIG_ENDIAN:
00306 return net_to_host(value);
00307 case BYTEORDER_LITTLE_ENDIAN:
00308 return le_to_host(value);
00309 }
00310 throw;
00311 }
00312
00313 I network() const {
00314 switch ( byte_order )
00315 {
00316 case BYTEORDER_HOST:
00317 return host_to_net(value);
00318 case BYTEORDER_NETWORK:
00319 case BYTEORDER_BIG_ENDIAN:
00320 return value;
00321 case BYTEORDER_LITTLE_ENDIAN:
00322 return le_to_net(value);
00323 }
00324 throw;
00325 }
00326
00327 I big_endian() const {
00328 return this->network();
00329 }
00330
00331 I little_endian() const {
00332 switch ( byte_order )
00333 {
00334 case BYTEORDER_HOST:
00335 return host_to_le(value);
00336 case BYTEORDER_NETWORK:
00337 case BYTEORDER_BIG_ENDIAN:
00338 return net_to_le(value);
00339 case BYTEORDER_LITTLE_ENDIAN:
00340 return value;
00341 }
00342 throw;
00343 }
00344
00345 I value;
00346
00347 protected:
00348 void convert_value_from_type_to_host()
00349 {
00350 switch ( byte_order )
00351 {
00352 case BYTEORDER_HOST:
00353 return;
00354 case BYTEORDER_NETWORK:
00355 case BYTEORDER_BIG_ENDIAN:
00356 value = net_to_host(value);
00357 case BYTEORDER_LITTLE_ENDIAN:
00358 value = le_to_host(value);
00359 }
00360 }
00361
00362 void convert_value_from_host_to_type()
00363 {
00364 switch ( byte_order )
00365 {
00366 case BYTEORDER_HOST:
00367 return;
00368 case BYTEORDER_NETWORK:
00369 case BYTEORDER_BIG_ENDIAN:
00370 value = host_to_net(value);
00371 case BYTEORDER_LITTLE_ENDIAN:
00372 value = host_to_le(value);
00373 }
00374 }
00375
00376 };
00377
00378 typedef Int<uint8_t> UInt8;
00379 typedef Int<int8_t> Int8;
00380 typedef Int<uint16_t> UInt16;
00381 typedef Int<int16_t> Int16;
00382 typedef Int<uint32_t> UInt32;
00383 typedef Int<int32_t> Int32;
00384 typedef Int<uint64_t> UInt64;
00385 typedef Int<int64_t> Int64;
00386
00387 template <typename T> Integer::operator T()
00388 {
00389 switch ( this->size() )
00390 {
00391 case 1:
00392 if ( this->int_type() == typeid(uint8_t) )
00393 {
00394 UInt8* uint8;
00395 uint8 = dynamic_cast<UInt8*>(this);
00396 return static_cast<T>(uint8->host());
00397 }
00398 else if ( this->int_type() == typeid(int8_t) )
00399 {
00400 Int8* int8;
00401 int8 = dynamic_cast<Int8*>(this);
00402 return static_cast<T>(int8->host());
00403 }
00404 break;
00405 case 2:
00406 if ( this->int_type() == typeid(uint16_t) )
00407 {
00408 UInt16* uint16;
00409 uint16 = dynamic_cast<UInt16*>(this);
00410 return static_cast<T>(uint16->host());
00411 }
00412 else if ( this->int_type() == typeid(int16_t) )
00413 {
00414 Int16* int16;
00415 int16 = dynamic_cast<Int16*>(this);
00416 return static_cast<T>(int16->host());
00417 }
00418 break;
00419 case 4:
00420 if ( this->int_type() == typeid(uint32_t) )
00421 {
00422 UInt32* uint32;
00423 uint32 = dynamic_cast<UInt32*>(this);
00424 return static_cast<T>(uint32->host());
00425 }
00426 else if ( this->int_type() == typeid(int32_t) )
00427 {
00428 Int32* int32;
00429 int32 = dynamic_cast<Int32*>(this);
00430 return static_cast<T>(int32->host());
00431 }
00432 break;
00433 case 8:
00434 if ( this->int_type() == typeid(uint64_t) )
00435 {
00436 UInt64* uint64;
00437 uint64 = dynamic_cast<UInt64*>(this);
00438 return static_cast<T>(uint64->host());
00439 }
00440 else if ( this->int_type() == typeid(int64_t) )
00441 {
00442 Int64* int64;
00443 int64 = dynamic_cast<Int64*>(this);
00444 return static_cast<T>(int64->host());
00445 }
00446 }
00447 throw std::logic_error("bit::Integer bad cast");
00448 }
00449
00450 template <typename T> Integer& Integer::operator = ( T i )
00451 {
00452 switch ( this->size() )
00453 {
00454 case 1:
00455 if ( this->int_type() == typeid(uint8_t) )
00456 {
00457 UInt8* uint8;
00458 uint8 = dynamic_cast<UInt8*>(this);
00459 *uint8 = (uint8_t)(i);
00460 }
00461 else if ( this->int_type() == typeid(int8_t) )
00462 {
00463 Int8* int8;
00464 int8 = dynamic_cast<Int8*>(this);
00465 *int8 = (int8_t)(i);
00466 }
00467 break;
00468 case 2:
00469 if ( this->int_type() == typeid(uint16_t) )
00470 {
00471 UInt16* uint16;
00472 uint16 = dynamic_cast<UInt16*>(this);
00473 *uint16 = (uint16_t)(i);
00474 }
00475 else if ( this->int_type() == typeid(int16_t) )
00476 {
00477 Int16* int16;
00478 int16 = dynamic_cast<Int16*>(this);
00479 *int16 = (int16_t)(i);
00480 }
00481 break;
00482 case 4:
00483 if ( this->int_type() == typeid(uint32_t) )
00484 {
00485 UInt32* uint32;
00486 uint32 = dynamic_cast<UInt32*>(this);
00487 *uint32 = (uint32_t)(i);
00488 }
00489 else if ( this->int_type() == typeid(int32_t) )
00490 {
00491 Int32* int32;
00492 int32 = dynamic_cast<Int32*>(this);
00493 *int32 = (int32_t)(i);
00494 }
00495 break;
00496 case 8:
00497 if ( this->int_type() == typeid(uint64_t) )
00498 {
00499 UInt64* uint64;
00500 uint64 = dynamic_cast<UInt64*>(this);
00501 *uint64 = (uint64_t)(i);
00502 }
00503 else if ( this->int_type() == typeid(int64_t) )
00504 {
00505 Int64* int64;
00506 int64 = dynamic_cast<Int64*>(this);
00507 *int64 = (int64_t)(i);
00508 }
00509 }
00510 return *this;
00511 }
00512
00513 }
00514
00515 #endif