LCIO  02.17
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BitField64.cc
Go to the documentation of this file.
1 #include "UTIL/BitField64.h"
2 
3 #include <cmath>
4 #include <algorithm>
5 
6 using namespace EVENT ;
7 
8 namespace UTIL{
9 
10 
11  BitFieldValue::BitFieldValue( lcio::long64& bitfield, const std::string& theName,
12  unsigned theOffset, int signedWidth ) :
13  _b(bitfield),
14  _mask(0),
15  _name( theName ),
16  _offset( theOffset ),
17  _width( abs( signedWidth ) ),
18  _minVal(0),
19  _maxVal(0),
20  _isSigned( signedWidth < 0 ) {
21 
22  // sanity check
23  if( _offset > 63 || _offset+_width > 64 ) {
24 
26  s << " BitFieldValue '" << _name << "': out of range - offset : "
27  << _offset << " width " << _width ;
28 
29  throw( Exception( s.str() ) ) ;
30  }
31 
32  _mask = ( ( 0x0001LL << _width ) - 1 ) << _offset ;
33 
34 
35  // compute extreme values for later checks
36  if( _isSigned ){
37 
38  _minVal = ( 1LL << ( _width - 1 ) ) - ( 1LL << _width ) ;
39  _maxVal = ( 1LL << ( _width - 1 ) ) - 1 ;
40 
41  } else {
42 
43  _maxVal = 0x0001<<_width ;
44  }
45 
46  // std::cout << " _mask :" << std::hex << _mask
47  // << std::dec << std::endl ;
48  // std::cout << " min " << _minVal
49  // << " max " << _maxVal
50  // << " width " << _width
51  // << std::endl ;
52 
53  }
54 
55 
57 
58  if( _isSigned ) {
59 
60  long64 val = ( _b & _mask ) >> _offset ;
61 
62  if( ( val & ( 1LL << ( _width - 1 ) ) ) != 0 ) { // negative value
63 
64  val -= ( 1LL << _width );
65  }
66 
67  return val ;
68 
69  } else {
70 
71  return ( _b & _mask ) >> _offset ;
72  }
73  }
74 
76 
77  // check range
78  if( in < _minVal || in > _maxVal ) {
79 
81  s << " BitFieldValue '" << _name << "': out of range : " << in
82  << " for width " << _width ;
83 
84  throw( Exception( s.str() ) );
85  }
86 
87  _b &= ~_mask ; // zero out the field's range
88 
89  _b |= ( ( in << _offset ) & _mask ) ;
90 
91  return *this ;
92  }
93 
94 
95 
96 
97  size_t BitField64::index( const std::string& name) const {
98 
99  IndexMap::const_iterator it = _map.find( name ) ;
100 
101  if( it != _map.end() )
102 
103  return it->second ;
104 
105  else
106  throw Exception(" BitFieldValue: unknown name: " + name ) ;
107  }
108 
109  unsigned BitField64::highestBit() const {
110 
111  unsigned hb(0) ;
112 
113  for(unsigned i=0;i<_fields.size();i++){
114 
115  if( hb < ( _fields[i]->offset() + _fields[i]->width() ) )
116  hb = _fields[i]->offset() + _fields[i]->width() ;
117  }
118  return hb ;
119  }
120 
121 
123 
124  std::stringstream os ;
125 
126  for(unsigned i=0;i<_fields.size();i++){
127 
128  if( i != 0 ) os << "," ;
129 
130  os << _fields[i]->name() << ":" << _fields[i]->value() ;
131 
132  }
133  return os.str() ;
134  }
135 
137 
138  std::stringstream os ;
139 
140  for(unsigned i=0;i<_fields.size();i++){
141 
142  if( i != 0 ) os << "," ;
143 
144  os << _fields[i]->name() << ":"
145  << _fields[i]->offset() << ":" ;
146 
147  if( _fields[i]->isSigned() )
148  os << "-" ;
149 
150  os << _fields[i]->width() ;
151 
152  }
153 // for( IndexMap::const_iterator it = _map.begin() ;
154 // it != _map.end() ; ++it ){
155 
156 // if( it != _map.begin() )
157 // os << "," ;
158 
159 // os << it->first << ":"
160 // << _fields[ it->second ]->offset() << ":" ;
161 
162 // if( _fields[ it->second ]->isSigned() )
163 // os << "-" ;
164 
165 // os << _fields[ it->second ]->width() ;
166 
167 // }
168 
169  return os.str() ;
170  }
171 
172  void BitField64::addField( const std::string& name, unsigned offset, int width ){
173 
174 
175  BitFieldValue* bfv = new BitFieldValue( _value, name, offset, width ) ;
176 
177  _fields.push_back( bfv ) ;
178 
179  _map[ name ] = _fields.size()-1 ;
180 
181  if( _joined & bfv->mask() ) {
182 
184  s << " BitFieldValue::addField(" << name << "): bits already used " << std::hex << _joined
185  << " for mask " << bfv->mask() ;
186 
187  throw( Exception( s.str() ) ) ;
188 
189  }
190 
191  _joined |= _fields.back()->mask() ;
192 
193  }
194 
195  void BitField64::init( const std::string& initString) {
196 
197  unsigned offset = 0 ;
198 
199  // need to compute bit field masks and offsets ...
200  std::vector<std::string> fieldDescriptors ;
201  LCTokenizer t( fieldDescriptors ,',') ;
202 
203  std::for_each( initString.begin(), initString.end(), t ) ;
204 
205  for(unsigned i=0; i< fieldDescriptors.size() ; i++ ){
206 
207  std::vector<std::string> subfields ;
208  LCTokenizer ts( subfields ,':') ;
209 
210  std::for_each( fieldDescriptors[i].begin(), fieldDescriptors[i].end(), ts );
211 
212  std::string name ;
213  int width ;
214  unsigned thisOffset ;
215 
216  switch( subfields.size() ){
217 
218  case 2:
219 
220  name = subfields[0] ;
221  width = atol( subfields[1].c_str() ) ;
222  thisOffset = offset ;
223 
224  offset += abs( width ) ;
225 
226  break ;
227 
228  case 3:
229  name = subfields[0] ;
230  thisOffset = atol( subfields[1].c_str() ) ;
231  width = atol( subfields[2].c_str() ) ;
232 
233  offset = thisOffset + abs( width ) ;
234 
235  break ;
236 
237  default:
238 
240  s << " BitField64: invalid number of subfields "
241  << fieldDescriptors[i] ;
242 
243  throw( Exception( s.str() ) ) ;
244  }
245 
246  addField( name , thisOffset, width ) ;
247  }
248  }
249 
250 
252 
253  os << " bitfield: 0x" << std::hex // << std::ios::width(16) << std::ios::fill('0') <<
254  << b._value << std::dec << std::endl ;
255 
256  for( BitField64::IndexMap::const_iterator it = b._map.begin() ;
257  it != b._map.end() ; ++it ){
258 
259  os << " " << it->first << " [" << b[ it->second ].offset() << ":" ;
260 
261  if( b[ it->second ].isSigned() ) os << "-" ;
262 
263  os << b[ it->second ].width() << "] : " ;
264 
265 
266  os << b[ it->second ].value()
267  << std::endl ;
268 
269  }
270 
271  return os ;
272  }
273 
274 } // namespace
275 
Base exception class for LCIO - all other exceptions extend this.
Definition: Exceptions.h:21
BitFieldValue & operator=(lcio::long64 in)
Assignment operator for user convenience.
Definition: BitField64.cc:75
lcio::long64 _joined
Definition: BitField64.h:252
unsigned highestBit() const
Highest bit used in fields [0-63].
Definition: BitField64.cc:109
std::ostream & operator<<(std::ostream &os, const BitField64 &b)
Operator for dumping BitField64 to streams.
Definition: BitField64.cc:251
std::vector< BitFieldValue * > _fields
Definition: BitField64.h:249
T endl(T...args)
std::string fieldDescription() const
Return a valid description string of all fields.
Definition: BitField64.cc:136
size_t index(const std::string &name) const
Index for field named &#39;name&#39;.
Definition: BitField64.cc:97
A bit field of 64bits that allows convenient declaration and manipulation of sub fields of various wi...
Definition: BitField64.h:132
Helper class for BitField64 that corresponds to one field value.
Definition: BitField64.h:55
lcio::ulong64 mask() const
The field&#39;s mask.
Definition: BitField64.h:101
T end(T...args)
std::string valueString() const
Return a string with a comma separated list of the current sub field values.
Definition: BitField64.cc:122
long long long64
64 bit signed integer,e.g.to be used for timestamps
Definition: LCIOTypes.h:14
STL class.
lcio::long64 value() const
Returns the current field value.
Definition: BitField64.cc:56
void addField(const std::string &name, unsigned offset, int width)
Add an additional field to the list.
Definition: BitField64.cc:172
std::string _name
Definition: BitField64.h:108
lcio::ulong64 _mask
Definition: BitField64.h:107
T str(T...args)
lcio::long64 & _b
Definition: BitField64.h:106
Helper class for string tokenization.
Definition: BitField64.h:21
lcio::long64 _value
Definition: BitField64.h:250
T find(T...args)
T size(T...args)
T begin(T...args)
T hex(T...args)
T for_each(T...args)
void init(const std::string &initString)
Decode the initialization string as described in the constructor.
Definition: BitField64.cc:195
STL class.
EVENT::long64 long64
Definition: LCReader.cc:27