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::pointer create_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( Data::const_pointer d ) = 0;
00058
00059 virtual void set_value( const void* mem, size_t size ) = 0;
00060
00066 virtual void set_value( Data::const_pointer 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(Data::const_pointer 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(Data::const_pointer 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( Data::const_pointer d ) {
00214 if ( d->size() < sizeof(I) )
00215 throw;
00216
00217 memcpy( &value, d->data(), sizeof(I) );
00218 }
00219
00225 virtual void set_value( const void* mem, size_t size ) {
00226 if ( size < sizeof(I) )
00227 throw;
00228
00229 memcpy( &value, mem, sizeof(I) );
00230 }
00231
00237 virtual void set_value( Data::const_pointer d, ByteOrder databo ) {
00238 if ( d->size() < sizeof(I) )
00239 throw;
00240
00241 memcpy( &value, d->data(), sizeof(I) );
00242
00243 switch ( byte_order ) {
00244 case BYTEORDER_HOST:
00245 switch ( databo ) {
00246 case BYTEORDER_HOST:
00247 break;
00248 case BYTEORDER_NETWORK:
00249 case BYTEORDER_BIG_ENDIAN:
00250 value = be_to_host(value);
00251 break;
00252 case BYTEORDER_LITTLE_ENDIAN:
00253 value = le_to_host(value);
00254 break;
00255 }
00256 break;
00257 case BYTEORDER_NETWORK:
00258 case BYTEORDER_BIG_ENDIAN:
00259 switch ( databo ) {
00260 case BYTEORDER_HOST:
00261 value = host_to_net(value);
00262 break;
00263 case BYTEORDER_NETWORK:
00264 case BYTEORDER_BIG_ENDIAN:
00265 break;
00266 case BYTEORDER_LITTLE_ENDIAN:
00267 value = le_to_net(value);
00268 break;
00269 }
00270 break;
00271 case BYTEORDER_LITTLE_ENDIAN:
00272 switch ( databo ) {
00273 case BYTEORDER_HOST:
00274 value = host_to_le(value);
00275 break;
00276 case BYTEORDER_NETWORK:
00277 case BYTEORDER_BIG_ENDIAN:
00278 value = net_to_le(value);
00279 break;
00280 case BYTEORDER_LITTLE_ENDIAN:
00281 break;
00282 }
00283 break;
00284 }
00285 }
00286
00287 virtual Data::pointer create_data() const
00288 {
00289 Data::pointer d = Data::create( sizeof(I) );
00290 memcpy( d->data(), &value, sizeof(I) );
00291 return d;
00292 }
00293
00294 virtual size_t size() const { return sizeof(I); }
00295
00296 virtual const void* voidptr() const { return &value; }
00297
00298 virtual const std::type_info& int_type() { return typeid(I); }
00299
00300 I host() const {
00301 switch ( byte_order )
00302 {
00303 case BYTEORDER_HOST:
00304 return value;
00305 case BYTEORDER_NETWORK:
00306 case BYTEORDER_BIG_ENDIAN:
00307 return net_to_host(value);
00308 case BYTEORDER_LITTLE_ENDIAN:
00309 return le_to_host(value);
00310 }
00311 throw;
00312 }
00313
00314 I network() const {
00315 switch ( byte_order )
00316 {
00317 case BYTEORDER_HOST:
00318 return host_to_net(value);
00319 case BYTEORDER_NETWORK:
00320 case BYTEORDER_BIG_ENDIAN:
00321 return value;
00322 case BYTEORDER_LITTLE_ENDIAN:
00323 return le_to_net(value);
00324 }
00325 throw;
00326 }
00327
00328 I big_endian() const {
00329 return this->network();
00330 }
00331
00332 I little_endian() const {
00333 switch ( byte_order )
00334 {
00335 case BYTEORDER_HOST:
00336 return host_to_le(value);
00337 case BYTEORDER_NETWORK:
00338 case BYTEORDER_BIG_ENDIAN:
00339 return net_to_le(value);
00340 case BYTEORDER_LITTLE_ENDIAN:
00341 return value;
00342 }
00343 throw;
00344 }
00345
00346 I value;
00347
00348 protected:
00349 void convert_value_from_type_to_host()
00350 {
00351 switch ( byte_order )
00352 {
00353 case BYTEORDER_HOST:
00354 return;
00355 case BYTEORDER_NETWORK:
00356 case BYTEORDER_BIG_ENDIAN:
00357 value = net_to_host(value);
00358 case BYTEORDER_LITTLE_ENDIAN:
00359 value = le_to_host(value);
00360 }
00361 }
00362
00363 void convert_value_from_host_to_type()
00364 {
00365 switch ( byte_order )
00366 {
00367 case BYTEORDER_HOST:
00368 return;
00369 case BYTEORDER_NETWORK:
00370 case BYTEORDER_BIG_ENDIAN:
00371 value = host_to_net(value);
00372 case BYTEORDER_LITTLE_ENDIAN:
00373 value = host_to_le(value);
00374 }
00375 }
00376
00377 };
00378
00379 typedef Int<uint8_t> UInt8;
00380 typedef Int<int8_t> Int8;
00381 typedef Int<uint16_t> UInt16;
00382 typedef Int<int16_t> Int16;
00383 typedef Int<uint32_t> UInt32;
00384 typedef Int<int32_t> Int32;
00385 typedef Int<uint64_t> UInt64;
00386 typedef Int<int64_t> Int64;
00387
00388 template <typename T> Integer::operator T()
00389 {
00390 switch ( this->size() )
00391 {
00392 case 1:
00393 if ( this->int_type() == typeid(uint8_t) )
00394 {
00395 UInt8* uint8;
00396 uint8 = dynamic_cast<UInt8*>(this);
00397 return static_cast<T>(uint8->host());
00398 }
00399 else if ( this->int_type() == typeid(int8_t) )
00400 {
00401 Int8* int8;
00402 int8 = dynamic_cast<Int8*>(this);
00403 return static_cast<T>(int8->host());
00404 }
00405 break;
00406 case 2:
00407 if ( this->int_type() == typeid(uint16_t) )
00408 {
00409 UInt16* uint16;
00410 uint16 = dynamic_cast<UInt16*>(this);
00411 return static_cast<T>(uint16->host());
00412 }
00413 else if ( this->int_type() == typeid(int16_t) )
00414 {
00415 Int16* int16;
00416 int16 = dynamic_cast<Int16*>(this);
00417 return static_cast<T>(int16->host());
00418 }
00419 break;
00420 case 4:
00421 if ( this->int_type() == typeid(uint32_t) )
00422 {
00423 UInt32* uint32;
00424 uint32 = dynamic_cast<UInt32*>(this);
00425 return static_cast<T>(uint32->host());
00426 }
00427 else if ( this->int_type() == typeid(int32_t) )
00428 {
00429 Int32* int32;
00430 int32 = dynamic_cast<Int32*>(this);
00431 return static_cast<T>(int32->host());
00432 }
00433 break;
00434 case 8:
00435 if ( this->int_type() == typeid(uint64_t) )
00436 {
00437 UInt64* uint64;
00438 uint64 = dynamic_cast<UInt64*>(this);
00439 return static_cast<T>(uint64->host());
00440 }
00441 else if ( this->int_type() == typeid(int64_t) )
00442 {
00443 Int64* int64;
00444 int64 = dynamic_cast<Int64*>(this);
00445 return static_cast<T>(int64->host());
00446 }
00447 }
00448 throw std::logic_error("bit::Integer bad cast");
00449 }
00450
00451 template <typename T> Integer& Integer::operator = ( T i )
00452 {
00453 switch ( this->size() )
00454 {
00455 case 1:
00456 if ( this->int_type() == typeid(uint8_t) )
00457 {
00458 UInt8* uint8;
00459 uint8 = dynamic_cast<UInt8*>(this);
00460 *uint8 = (uint8_t)(i);
00461 }
00462 else if ( this->int_type() == typeid(int8_t) )
00463 {
00464 Int8* int8;
00465 int8 = dynamic_cast<Int8*>(this);
00466 *int8 = (int8_t)(i);
00467 }
00468 break;
00469 case 2:
00470 if ( this->int_type() == typeid(uint16_t) )
00471 {
00472 UInt16* uint16;
00473 uint16 = dynamic_cast<UInt16*>(this);
00474 *uint16 = (uint16_t)(i);
00475 }
00476 else if ( this->int_type() == typeid(int16_t) )
00477 {
00478 Int16* int16;
00479 int16 = dynamic_cast<Int16*>(this);
00480 *int16 = (int16_t)(i);
00481 }
00482 break;
00483 case 4:
00484 if ( this->int_type() == typeid(uint32_t) )
00485 {
00486 UInt32* uint32;
00487 uint32 = dynamic_cast<UInt32*>(this);
00488 *uint32 = (uint32_t)(i);
00489 }
00490 else if ( this->int_type() == typeid(int32_t) )
00491 {
00492 Int32* int32;
00493 int32 = dynamic_cast<Int32*>(this);
00494 *int32 = (int32_t)(i);
00495 }
00496 break;
00497 case 8:
00498 if ( this->int_type() == typeid(uint64_t) )
00499 {
00500 UInt64* uint64;
00501 uint64 = dynamic_cast<UInt64*>(this);
00502 *uint64 = (uint64_t)(i);
00503 }
00504 else if ( this->int_type() == typeid(int64_t) )
00505 {
00506 Int64* int64;
00507 int64 = dynamic_cast<Int64*>(this);
00508 *int64 = (int64_t)(i);
00509 }
00510 }
00511 return *this;
00512 }
00513
00514 }
00515
00516 #endif