lcdd/include
diff -u -r1.8 -r1.9
--- IdFactory.hh 27 Jun 2005 21:45:20 -0000 1.8
+++ IdFactory.hh 15 Jul 2005 22:43:55 -0000 1.9
@@ -1,4 +1,4 @@
-// $Header: /cvs/lcd/lcdd/include/IdFactory.hh,v 1.8 2005/06/27 21:45:20 jeremy Exp $
+// $Header: /cvs/lcd/lcdd/include/IdFactory.hh,v 1.9 2005/07/15 22:43:55 jeremy Exp $
#ifndef IdFactory_hh
#define IdFactory_hh 1
@@ -31,6 +31,8 @@
typedef unsigned int Bits;
+ static const Bits MASK_ON;
+
public:
virtual ~IdFactory()
@@ -44,13 +46,26 @@
public:
- // create Id64bit from IdVec
+ /* Create an Id64bit from the input IdVec and its matching specification. */
static Id64bit createId64bit(const IdVec& idvec, IdSpec* idspec);
+ /*
+ * TJ's suggestion for making a bit mask.
+ * @param len length of mask
+ */
+ static inline Bits makeBitMask(IdField::SizeType len);
+
+ /**
+ * Check that the given value does not overflow the given mask.
+ *
+ * @return If overflow, then returns the bits outside the mask. Otherwise, returns 0.
+ */
+ static inline Bits checkOverflow(Id64bit::ElementType field_val, Bits mask);
+
// create IdVec ordered by this SD's idspec, or empty vec if sd does not have an idspec
static IdVec createOrderedIdVec(G4Step* aStep, const G4SensitiveDetector* sd);
- // lkp bin value by field name in segmentation
+ /* lkp bin value by field name in segmentation */
static int findFieldIdxInSegmentation(G4Segmentation*, const std::string& field_name);
/* Check if PV list has PVid with given label. */
lcdd/src
diff -u -r1.17 -r1.18
--- IdFactory.cc 27 Jun 2005 21:45:56 -0000 1.17
+++ IdFactory.cc 15 Jul 2005 22:43:56 -0000 1.18
@@ -1,4 +1,4 @@
-// $Header: /cvs/lcd/lcdd/src/IdFactory.cc,v 1.17 2005/06/27 21:45:56 jeremy Exp $
+// $Header: /cvs/lcd/lcdd/src/IdFactory.cc,v 1.18 2005/07/15 22:43:56 jeremy Exp $
// set for verbose output from this class
//#define ID_DEBUG 1
@@ -18,6 +18,8 @@
using namespace std;
+IdFactory::Bits const IdFactory::MASK_ON = 0xFFFFFFFF;
+
Id64bit IdFactory::createId64bit(const IdVec& idvec, IdSpec* idspec)
{
#ifdef ID_DEBUG
@@ -29,58 +31,62 @@
std::cout << "idspec bitLength: " << idspec->getBitLength() << std::endl;
#endif
- // (idvec size == idspec size) or die
+ /* IdVec (expanded id) size must equal IdSpec size or die. */
if ( idvec.size() != idspec->getNumFields() ) {
- std::cerr << "FATAL ERROR: idspec size != idvec size." << std::endl;
- assert( 0 );
+ G4Exception("FATAL ERROR: idspec size != idvec size.");
}
- // new 64-bit id to return
+ /* Make a 64-bit id to return. */
Id64bit id64;
- // 2 member array for ids 1 & 2 (2x32-bit int)
+ /* A 2 member array for cell ids 1 & 2 (2x32-bit int). */
Bits id64_val[2] = { 0, 0 };
-
- // starting id idx = 0
size_t id64_val_idx = 0;
- // ptr to current idx
+ /* Ptr to value of current idx. */
Bits* id64_val_ptr = &id64_val[id64_val_idx];
- // loop vars
- Bits field_bit_len = 0;
- Bits curr_bit = 0;
-
- // ptr to the current idfield
+ /* Ptr to the current idfield. */
IdField* id_field = 0;
- // current idx in spec of idfield
- IdSpec::SizeType idspec_idx = 0;
-
- // flag that next 32-bit id has been reached
+ /* Flag indicating that next 32-bit id has been reached. */
bool next_id = false;
+ /* loop vars */
+ IdField::SizeType field_bit_len = 0;
+ Bits curr_bit = 0;
+ IdSpec::SizeType idspec_idx = 0;
+
+ /* Loop over the IdVec, packing its values into the 64-bit Id
+ using information from the IdSpec. */
for (IdVec::ElementVector::const_iterator iter = idvec.getFieldsBegin();
iter != idvec.getFieldsEnd();
iter++) {
- // get the field ptr from idspec
+ /* field ptr from idspec */
id_field = idspec->getIdField( idspec_idx );
assert( id_field );
- // get id value of field
+ /* id value of field */
Id64bit::ElementType field_val = (Id64bit::ElementType) *iter;
- // get field length
+ /* field length */
field_bit_len = id_field->getLength();
- // get field start
+ /* field start */
Bits field_start = id_field->getStart();
- // check if on 2nd dbl word
- if ( field_start >= 32 ) {
+ /* Don't allow crossing of 32-bit boundary.
+ FIXME: See http://jira.slac.stanford.edu/browse/LCDD-21
+ */
+ if ( ( field_start < 32 ) && (field_start + field_bit_len > 32 ) ) {
+ G4cerr << "Field <" << id_field->getLabel() << "> crosses the 32-bit boundary." << G4endl;
+ G4Exception("FATAL ERROR: Ids are currently not allowed to cross the 32-bit boundary.");
+ }
+ /* check if on 2nd dbl word. */
+ else if ( field_start >= 32 ) {
- // if 1st time, set id val pntr
+ /* If 1st time, set id val pntr. */
if (!next_id) {
#ifdef ID_DEBUG
std::cout << "setting ptr to next id" << std::endl;
@@ -90,7 +96,7 @@
next_id = true;
}
- // adjust start idx for position in next 32-bit id
+ /* Adjust start idx for position in next 32-bit id. */
field_start -= 32;
}
@@ -104,20 +110,26 @@
std::cout << "field_bit_len: " << dec << field_bit_len << std::endl;
#endif
- // TJ's suggestion for making a bit mask with len = field_bit_len.
- Bits field_mask = (1 << field_bit_len) - 1;
+ Bits field_mask = makeBitMask(field_bit_len);
+
+ /* Check that this value doesn't overflow the assigned length. */
+ if ( checkOverflow(field_val, field_mask) != 0 ) {
+ G4cerr << "Value <" << field_val << "> is too big for the field <" << id_field->getLabel() << ">." << G4endl;
+ G4Exception("FATAL ERROR: Id value too large for field.");
+ }
#ifdef ID_DEBUG
std::cout << "field_mask: " << hex << field_mask << std::endl;
+ std::cout << "field_check: " << hex << field_check << std::endl;
#endif
- // apply bit mask and shift to proper left pos
+ /* Apply bit mask and shift to proper left pos. */
Bits field_val_shifted_masked = ( field_val & field_mask ) << field_start;
- // AND into id val
+ /* AND into the current id val. */
(*id64_val_ptr) = (*id64_val_ptr) | field_val_shifted_masked;
- // incr curr bit for next starting pos
+ /* Set current bit to next start pos. */
curr_bit += id_field->getLength();
#ifdef ID_DEBUG
@@ -125,7 +137,7 @@
std::cout << std::endl;
#endif
- // incr idspec idx
+ /* Increment the idspec idx. */
++idspec_idx;
}
@@ -137,13 +149,23 @@
std::cout << std::endl << std::endl;
#endif
- // set the two 32-bit ids in the packed id to return
+ /* Set the two 32-bit ids in the packed id to return. */
id64.setId0( id64_val[0] );
id64.setId1( id64_val[1] );
return id64;
}
+inline IdFactory::Bits IdFactory::makeBitMask(IdField::SizeType len)
+{
+ return (Bits)((1 << len) - 1);
+}
+
+inline IdFactory::Bits IdFactory::checkOverflow(Id64bit::ElementType val, Bits mask)
+{
+ return (Bits)((mask ^ MASK_ON) & val);
+}
+
IdVec IdFactory::createOrderedIdVec(G4Step* aStep, const G4SensitiveDetector* sd)
{
assert( aStep );
@@ -214,9 +236,9 @@
}
}
#ifdef ID_DEBUG
- else {
- std::cout << "not in volume (copyNum)" << std::endl;
- }
+ else {
+ std::cout << "not in volume (copyNum)" << std::endl;
+ }
#endif
/* Not found anywhere, so we need to die. */