/data3/calcul/jacquem/working_dir/Micromegas/micromegasFrameWork/lcio/src/cpp/src/UTIL/BitField64.cc

Go to the documentation of this file.
00001 #include "UTIL/BitField64.h"
00002 
00003 #include <cmath>
00004 #include <algorithm>
00005 
00006 using namespace EVENT ;
00007 
00008 namespace UTIL{
00009   
00010   
00011     BitFieldValue::BitFieldValue( lcio::long64& bitfield, const std::string& name, 
00012                                   unsigned offset, int signedWidth ) :
00013     _b(bitfield),
00014     _mask(0), 
00015     _name( name ), 
00016     _offset( offset ),
00017     _width( abs( signedWidth ) ),
00018     _minVal(0),
00019     _maxVal(0),
00020     _isSigned( signedWidth < 0 ) {
00021     
00022     // sanity check
00023     if( offset < 0 || offset > 63 || offset+_width > 64 ) {
00024       
00025       std::stringstream s ;
00026       s << " BitFieldValue: out of range -  offset : " 
00027         << offset  << " width " << _width ; 
00028       
00029       throw( Exception( s.str() ) ) ;
00030     }
00031     
00032     _mask = ( ( 0x0001LL << _width ) - 1 ) << offset ;
00033     
00034     
00035     // compute extreme values for later checks
00036     if( _isSigned ){
00037       
00038       _minVal =  ( 1LL << ( _width - 1 ) ) - ( 1LL << _width )  ;
00039       _maxVal =  ( 1LL << ( _width - 1 ) ) - 1 ;
00040       
00041     } else {
00042       
00043       _maxVal = 0x0001<<_width  ;
00044     }
00045     
00046     //       std::cout << " _mask :" << std::hex << _mask  
00047     //                 <<  std::dec <<  std::endl ; 
00048     //       std::cout << " min " << _minVal 
00049     //          << " max " << _maxVal
00050     //          << " width " << _width 
00051     //          << std::endl ; 
00052  
00053   }
00054   
00055 
00056   long64 BitFieldValue::value() const { 
00057       
00058     if(  _isSigned   ) {
00059 
00060       long64 val = ( _b & _mask ) >> _offset ;
00061       
00062       if( ( val  & ( 1LL << ( _width - 1 ) ) ) != 0 ) { // negative value
00063           
00064         val -= ( 1LL << _width );
00065       }
00066         
00067       return val ;
00068 
00069     } else { 
00070       
00071       return  ( _b & _mask ) >> _offset ;
00072     }
00073   }
00074 
00075   BitFieldValue& BitFieldValue::operator=(long64 in) {
00076     
00077     // check range 
00078     if( in < _minVal || in > _maxVal  ) {
00079       
00080       std::stringstream s ;
00081       s << " BitFieldValue: out of range : " << in 
00082         << " for width " << _width ; 
00083       
00084       throw( Exception( s.str() ) );
00085     }
00086     
00087     _b &= ~_mask ;  // zero out the field's range
00088     
00089     _b |=  ( (  in  << _offset )  & _mask  ) ; 
00090     
00091     return *this ;
00092   }
00093   
00094 
00095 
00096 
00097   size_t BitField64::index( const std::string& name) const {
00098     
00099     IndexMap::const_iterator it = _map.find( name ) ;
00100     
00101     if( it != _map.end() ) 
00102       
00103       return it->second  ;
00104     
00105     else
00106       throw Exception(" BitFieldValue: unknown name: " + name ) ;
00107   }
00108   
00109   unsigned BitField64::highestBit() {
00110 
00111     unsigned hb(0) ;
00112 
00113     for(unsigned i=0;i<_fields.size();i++){
00114 
00115       if( hb < ( _fields[i]->offset() + _fields[i]->width() ) )
00116         hb = _fields[i]->offset() + _fields[i]->width()  ;
00117     }    
00118     return hb ;
00119   }
00120 
00121 
00122   std::string BitField64::valueString() const {
00123 
00124     std::stringstream  os ;
00125 
00126     for(unsigned i=0;i<_fields.size();i++){
00127       
00128       if( i != 0 )   os << "," ;
00129 
00130       os << _fields[i]->name() <<  ":" << _fields[i]->value() ;
00131 
00132     }
00133     return os.str() ;
00134   }
00135   
00136   std::string BitField64::fieldDescription() const {
00137     
00138     std::stringstream  os ;
00139     
00140     for(unsigned i=0;i<_fields.size();i++){
00141       
00142       if( i != 0 )   os << "," ;
00143       
00144       os << _fields[i]->name() <<  ":"
00145          << _fields[i]->offset() << ":" ;
00146       
00147       if(  _fields[i]->isSigned()  )  
00148         os << "-" ;
00149       
00150       os  << _fields[i]->width() ;
00151       
00152     }
00153 //     for( IndexMap::const_iterator it = _map.begin()  ;
00154 //       it !=  _map.end() ; ++it ){
00155 
00156 //       if( it !=  _map.begin() )
00157 //      os << "," ;
00158       
00159 //       os << it->first <<  ":"
00160 //       << _fields[ it->second ]->offset() << ":" ;
00161       
00162 //       if(  _fields[ it->second ]->isSigned()  )  
00163 //      os << "-" ;
00164 
00165 //       os  << _fields[ it->second ]->width() ;
00166 
00167 //     }
00168     
00169     return os.str() ;
00170   }
00171 
00172   void BitField64::addField( const std::string& name,  unsigned offset, int width ){
00173 
00174       
00175     BitFieldValue* bfv =  new  BitFieldValue( _value, name, offset, width ) ;
00176 
00177     _fields.push_back(  bfv ) ;
00178     
00179     _map[ name ] = _fields.size()-1 ;
00180 
00181     if( _joined & bfv->mask()  ) {
00182       
00183       std::stringstream s ;
00184       s << " BitFieldValue: bits already used " << std::hex << _joined
00185         << " for mask " <<  bfv->mask()   ; 
00186 
00187       throw( Exception( s.str() ) ) ;
00188       
00189     }
00190 
00191     _joined |= _fields.back()->mask() ;
00192 
00193   }
00194 
00195   void BitField64::init( const std::string& initString) {
00196 
00197     unsigned offset = 0  ;
00198     
00199     // need to compute bit field masks and offsets ...
00200     std::vector<std::string> fieldDescriptors ;
00201     LCTokenizer t( fieldDescriptors ,',') ;
00202 
00203     std::for_each( initString.begin(), initString.end(), t ) ; 
00204 
00205     for(unsigned i=0; i< fieldDescriptors.size() ; i++ ){
00206       
00207       std::vector<std::string> subfields ;
00208       LCTokenizer ts( subfields ,':') ;
00209       
00210       std::for_each( fieldDescriptors[i].begin(), fieldDescriptors[i].end(), ts );
00211 
00212       std::string name ; 
00213       int  width ; 
00214       unsigned thisOffset ;
00215 
00216       switch( subfields.size() ){
00217         
00218       case 2: 
00219 
00220         name = subfields[0] ; 
00221         width = atol( subfields[1].c_str()  ) ;
00222         thisOffset = offset ;
00223 
00224         offset += abs( width ) ;
00225         
00226         break ;
00227         
00228       case 3: 
00229         name = subfields[0] ;
00230         thisOffset = atol( subfields[1].c_str()  ) ;
00231         width = atol( subfields[2].c_str()  ) ;
00232 
00233         offset = thisOffset + abs( width ) ;
00234 
00235         break ;
00236         
00237       default:
00238 
00239         std::stringstream s ;
00240         s << " BitField64: invalid number of subfields " 
00241           <<  fieldDescriptors[i] ;
00242 
00243         throw( Exception( s.str() ) ) ;
00244       }
00245 
00246       addField( name , thisOffset, width ) ;
00247     }
00248   }
00249 
00250 
00251   std::ostream& operator<<(std::ostream& os, const BitField64& b){
00252 
00253     os << " bitfield:  0x" << std::hex // << std::ios::width(16) << std::ios::fill('0') <<
00254        << b._value << std::dec << std::endl ;
00255 
00256     for( BitField64::IndexMap::const_iterator it = b._map.begin()  ;
00257          it !=  b._map.end() ; ++it ){
00258       
00259       os << "  " << it->first << " [" <<  b[ it->second ].offset()  << ":"  ;
00260       
00261       if(  b[ it->second ].isSigned()  )  os << "-" ;
00262       
00263       os <<  b[ it->second ].width() << "]  : "  ;
00264       
00265       
00266       os <<    b[ it->second ].value() 
00267          << std::endl ;
00268       
00269     }
00270   
00271     return os ;
00272   } 
00273 
00274 } // namespace
00275  

Generated on Mon Jan 7 13:15:21 2013 for MicromegasFramework by  doxygen 1.4.7