debian/libbit-dev/usr/include/bit-0.3/bit/integer.h

00001 /***************************************************************************
00002 *   Copyright (C) 2001 by Rick L. Vinyard, Jr.                            *
00003 *   rvinyard@cs.nmsu.edu                                                  *
00004 *                                                                         *
00005 *   This program is free software; you can redistribute it and/or modify  *
00006 *   it under the terms of the GNU Lesser General Public License as        *
00007 *   published by the Free Software Foundation version 2.1.                *
00008 *                                                                         *
00009 *   This program is distributed in the hope that it will be useful,       *
00010 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012 *   GNU General Public License for more details.                          *
00013 *                                                                         *
00014 *   You should have received a copy of the GNU Lesser General Public      *
00015 *   License along with this library; if not, write to the                 *
00016 *   Free Software Foundation, Inc.,                                       *
00017 *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
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

Generated on Tue Mar 13 20:00:01 2007 by  doxygen 1.5.1