Print

Print


Commit in lcdd on MAIN
include/IdFactory.hh+18-31.8 -> 1.9
src/IdFactory.cc+58-361.17 -> 1.18
+76-39
2 modified files
Added value vs. field len check to IdFactory.  Fixed LCDD-4.

lcdd/include
IdFactory.hh 1.8 -> 1.9
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
IdFactory.cc 1.17 -> 1.18
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. */
CVSspam 0.2.8