File indexing completed on 2025-02-22 09:36:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <DDSegmentation/BitFieldCoder.h>
0012
0013 #include <cmath>
0014 #include <algorithm>
0015 #include <stdexcept>
0016
0017 namespace dd4hep{
0018
0019 namespace DDSegmentation {
0020
0021 BitFieldElement::BitFieldElement( const std::string& fieldName,
0022 unsigned fieldOffset, int signedWidth ) :
0023 _mask(0),
0024 _offset( fieldOffset ),
0025 _width( abs( signedWidth ) ),
0026 _minVal(0),
0027 _maxVal(0),
0028 _isSigned( signedWidth < 0 ),
0029 _name( fieldName ) {
0030
0031
0032 if( _offset > 63 || _offset+_width > 64 ) {
0033
0034 std::stringstream s ;
0035 s << " BitFieldElement '" << _name << "': out of range - offset : "
0036 << _offset << " width " << _width ;
0037
0038 throw( std::runtime_error( s.str() ) ) ;
0039 }
0040
0041 _mask = ( ( 0x0001LL << _width ) - 1 ) << _offset ;
0042
0043
0044
0045 if( _isSigned ){
0046
0047 _minVal = ( 1LL << ( _width - 1 ) ) - ( 1LL << _width ) ;
0048 _maxVal = ( 1LL << ( _width - 1 ) ) - 1 ;
0049
0050 } else {
0051 _maxVal = 0x0001<<_width ;
0052 }
0053 }
0054
0055 FieldID BitFieldElement::value(CellID id) const {
0056 if( _isSigned ) {
0057 FieldID val = ( id & _mask ) >> _offset ;
0058 if( ( val & ( 1LL << ( _width - 1 ) ) ) != 0 ) {
0059 val -= ( 1LL << _width );
0060 }
0061 return val ;
0062 } else {
0063 return ( id & _mask ) >> _offset ;
0064 }
0065 }
0066
0067 void BitFieldElement::set(CellID& field, FieldID in) const {
0068
0069
0070 if( in < _minVal || in > _maxVal ) {
0071 std::stringstream s ;
0072 s << " BitFieldElement '" << _name << "': out of range : " << in
0073 << " for width " << _width ;
0074 throw( std::runtime_error( s.str() ) );
0075 }
0076
0077 field &= ~_mask ;
0078 field |= ( ( in << _offset ) & _mask ) ;
0079 }
0080
0081
0082
0083
0084 size_t BitFieldCoder::index( const std::string& name) const {
0085
0086 IndexMap::const_iterator it = _map.find( name ) ;
0087
0088 if( it != _map.end() )
0089
0090 return it->second ;
0091
0092 else
0093 throw std::runtime_error(" BitFieldElement: unknown name: " + name ) ;
0094 }
0095
0096 unsigned BitFieldCoder::highestBit() const {
0097
0098 unsigned hb(0) ;
0099
0100 for(unsigned i=0;i<_fields.size();i++){
0101
0102 if( hb < ( _fields[i].offset() + _fields[i].width() ) )
0103 hb = _fields[i].offset() + _fields[i].width() ;
0104 }
0105 return hb ;
0106 }
0107
0108
0109 std::string BitFieldCoder::valueString(CellID bitfield) const {
0110
0111 std::stringstream os ;
0112
0113 for(unsigned i=0;i<_fields.size();i++){
0114
0115 if( i != 0 ) os << "," ;
0116
0117 os << _fields[i].name() << ":" << _fields[i].value(bitfield) ;
0118
0119 }
0120 return os.str() ;
0121 }
0122
0123 std::string BitFieldCoder::fieldDescription() const {
0124
0125 std::stringstream os ;
0126
0127 for(unsigned i=0;i<_fields.size();i++){
0128
0129 if( i != 0 ) os << "," ;
0130
0131 os << _fields[i].name() << ":"
0132 << _fields[i].offset() << ":" ;
0133
0134 if( _fields[i].isSigned() )
0135 os << "-" ;
0136
0137 os << _fields[i].width() ;
0138
0139 }
0140
0141 return os.str() ;
0142 }
0143
0144 void BitFieldCoder::addField( const std::string& name, unsigned offset, int width ){
0145
0146
0147 _fields.emplace_back(name, offset, width);
0148 BitFieldElement& bfv = _fields.back() ;
0149
0150 _map[ name ] = _fields.size()-1 ;
0151
0152 if( _joined & bfv.mask() ) {
0153
0154 std::stringstream s ;
0155 s << " BitFieldElement::addField(" << name << "): bits already used " << std::hex << _joined
0156 << " for mask " << bfv.mask() ;
0157
0158 throw( std::runtime_error( s.str() ) ) ;
0159
0160 }
0161
0162 _joined |= bfv.mask() ;
0163
0164 }
0165
0166 void BitFieldCoder::init( const std::string& initString) {
0167
0168 unsigned offset = 0 ;
0169
0170
0171 std::vector<std::string> fieldDescriptors ;
0172 StringTokenizer t( fieldDescriptors ,',') ;
0173
0174 std::for_each( initString.begin(), initString.end(), t ) ;
0175
0176 for(unsigned i=0; i< fieldDescriptors.size() ; i++ ){
0177
0178 std::vector<std::string> subfields ;
0179 StringTokenizer ts( subfields ,':') ;
0180
0181 std::for_each( fieldDescriptors[i].begin(), fieldDescriptors[i].end(), ts );
0182
0183 std::string name ;
0184 int width ;
0185 unsigned thisOffset ;
0186
0187 switch( subfields.size() ){
0188
0189 case 2:
0190
0191 name = subfields[0] ;
0192 width = atol( subfields[1].c_str() ) ;
0193 thisOffset = offset ;
0194
0195 offset += abs( width ) ;
0196
0197 break ;
0198
0199 case 3:
0200 name = subfields[0] ;
0201 thisOffset = atol( subfields[1].c_str() ) ;
0202 width = atol( subfields[2].c_str() ) ;
0203
0204 offset = thisOffset + abs( width ) ;
0205
0206 break ;
0207
0208 default:
0209
0210 std::stringstream s ;
0211 s << " BitFieldCoder: invalid number of subfields "
0212 << fieldDescriptors[i] ;
0213
0214 throw( std::runtime_error( s.str() ) ) ;
0215 }
0216
0217 addField( name , thisOffset, width ) ;
0218 }
0219 }
0220
0221
0222
0223
0224 }
0225
0226 }