BitFieldCoder.cxx
Go to the documentation of this file.
2 
3 #include <cmath>
4 #include <algorithm>
5 #include <stdexcept>
6 
7 namespace gar {
8  namespace geo {
9 
10  BitFieldValue::BitFieldValue( const std::string& fieldName, unsigned fieldOffset, int signedWidth )
11  : _mask(0), _offset( fieldOffset ), _width( abs( signedWidth ) ), _minVal(0), _maxVal(0), _isSigned( signedWidth < 0 ), _name( fieldName )
12  {
13  // sanity check
14  if( _offset > 63 || _offset+_width > 64 ) {
15 
16  std::stringstream s ;
17  s << " BitFieldValue '" << _name << "': out of range - offset : "
18  << _offset << " width " << _width ;
19 
20  throw( std::runtime_error( s.str() ) ) ;
21  }
22 
23  _mask = ( ( 0x0001LL << _width ) - 1 ) << _offset ;
24 
25 
26  // compute extreme values for later checks
27  if( _isSigned ){
28 
29  _minVal = ( 1LL << ( _width - 1 ) ) - ( 1LL << _width ) ;
30  _maxVal = ( 1LL << ( _width - 1 ) ) - 1 ;
31 
32  } else {
33 
34  _maxVal = 0x0001<<_width ;
35  }
36  }
37 
38  //----------------------------------------------------------------------------
40  {
41  if( _isSigned )
42  {
43  long64 val = ( id & _mask ) >> _offset ;
44  if( ( val & ( 1LL << ( _width - 1 ) ) ) != 0 )
45  {
46  // negative value
47  val -= ( 1LL << _width );
48  }
49 
50  return val ;
51  }
52  else
53  {
54  return ( id & _mask ) >> _offset ;
55  }
56  }
57 
58  //----------------------------------------------------------------------------
59  void BitFieldValue::set(long64& field, long64 in) const {
60 
61  // check range
62  if( in < _minVal || in > _maxVal ) {
63 
64  std::stringstream s ;
65  s << " BitFieldValue '" << _name << "': out of range : " << in
66  << " for width " << _width ;
67 
68  throw( std::runtime_error( s.str() ) );
69  }
70 
71  field &= ~_mask ; // zero out the field's range
72 
73  field |= ( ( in << _offset ) & _mask ) ;
74 
75  }
76 
77  //----------------------------------------------------------------------------
78  size_t BitFieldCoder::index( const std::string& name) const {
79 
80  IndexMap::const_iterator it = _map.find( name ) ;
81 
82  if( it != _map.end() )
83 
84  return it->second ;
85 
86  else
87  throw std::runtime_error(" BitFieldValue: unknown name: " + name ) ;
88  }
89 
90  //----------------------------------------------------------------------------
91  unsigned BitFieldCoder::highestBit() const {
92 
93  unsigned hb(0) ;
94 
95  for(unsigned i=0;i<_fields.size();i++){
96 
97  if( hb < ( _fields[i].offset() + _fields[i].width() ) )
98  hb = _fields[i].offset() + _fields[i].width() ;
99  }
100  return hb ;
101  }
102 
103  //----------------------------------------------------------------------------
105 
106  std::stringstream os ;
107 
108  for(unsigned i=0;i<_fields.size();i++){
109 
110  if( i != 0 ) os << "," ;
111 
112  os << _fields[i].name() << ":" << _fields[i].value(bitfield) ;
113 
114  }
115  return os.str() ;
116  }
117 
118  //----------------------------------------------------------------------------
120 
121  std::stringstream os ;
122 
123  for(unsigned i=0;i<_fields.size();i++){
124 
125  if( i != 0 ) os << "," ;
126 
127  os << _fields[i].name() << ":"
128  << _fields[i].offset() << ":" ;
129 
130  if( _fields[i].isSigned() )
131  os << "-" ;
132 
133  os << _fields[i].width() ;
134 
135  }
136 
137  return os.str() ;
138  }
139 
140  //----------------------------------------------------------------------------
141  void BitFieldCoder::addField( const std::string& name, unsigned offset, int width ){
142 
143 
144  _fields.push_back( BitFieldValue( name, offset, width ) ) ;
145 
146  BitFieldValue& bfv = _fields.back() ;
147 
148  _map[ name ] = _fields.size()-1 ;
149 
150  if( _joined & bfv.mask() ) {
151 
152  std::stringstream s ;
153  s << " BitFieldValue::addField(" << name << "): bits already used " << std::hex << _joined
154  << " for mask " << bfv.mask() ;
155 
156  throw( std::runtime_error( s.str() ) ) ;
157 
158  }
159 
160  _joined |= bfv.mask() ;
161 
162  }
163 
164  //----------------------------------------------------------------------------
165  void BitFieldCoder::init( const std::string& initString) {
166 
167  unsigned offset = 0 ;
168 
169  // need to compute bit field masks and offsets ...
170  std::vector<std::string> fieldDescriptors ;
171  Tokenizer t( fieldDescriptors ,',') ;
172 
173  std::for_each( initString.begin(), initString.end(), t ) ;
174 
175  for(unsigned i=0; i< fieldDescriptors.size() ; i++ ){
176 
177  std::vector<std::string> subfields ;
178  Tokenizer ts( subfields ,':') ;
179 
180  std::for_each( fieldDescriptors[i].begin(), fieldDescriptors[i].end(), ts );
181 
182  std::string name ;
183  int width ;
184  unsigned thisOffset ;
185 
186  switch( subfields.size() ){
187 
188  case 2:
189 
190  name = subfields[0] ;
191  width = atol( subfields[1].c_str() ) ;
192  thisOffset = offset ;
193 
194  offset += abs( width ) ;
195 
196  break ;
197 
198  case 3:
199  name = subfields[0] ;
200  thisOffset = atol( subfields[1].c_str() ) ;
201  width = atol( subfields[2].c_str() ) ;
202 
203  offset = thisOffset + abs( width ) ;
204 
205  break ;
206 
207  default:
208 
209  std::stringstream s ;
210  s << " BitFieldCoder: invalid number of subfields "
211  << fieldDescriptors[i] ;
212 
213  throw( std::runtime_error( s.str() ) ) ;
214  }
215 
216  addField( name , thisOffset, width ) ;
217  }
218  }
219  }
220 } // namespace
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
BitFieldValue()=default
Default constructor.
Helper class for BitFieldCoder that corresponds to one field value.
Definition: BitFieldCoder.h:49
std::string string
Definition: nybbler.cc:12
std::string fieldDescription() const
long long long64
Definition: BitFieldCoder.h:18
intermediate_table::const_iterator const_iterator
QTextStream & hex(QTextStream &s)
unsigned highestBit() const
void set(long64 &bitfield, long64 value) const
T abs(T value)
void init(const std::string &initString)
ulong64 mask() const
Definition: BitFieldCoder.h:90
void addField(const std::string &name, unsigned offset, int width)
long64 value(long64 bitfield) const
calculate this field&#39;s value given an external 64 bit bitmap
std::string valueString(ulong64 bitfield) const
General GArSoft Utilities.
unsigned offset() const
Definition: BitFieldCoder.h:81
unsigned width() const
Definition: BitFieldCoder.h:84
size_t index(const std::string &name) const
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
bool isSigned() const
Definition: BitFieldCoder.h:87
const std::string & name() const
Definition: BitFieldCoder.h:78
LArSoft geometry interface.
Definition: ChannelGeo.h:16
unsigned long long ulong64
Definition: BitFieldCoder.h:19
static QCString * s
Definition: config.cpp:1042