ZMinput.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 // ---------------------------------------------------------------------------
00003 //
00004 // This file is a part of the CLHEP - a Class Library for High Energy Physics.
00005 //
00006 //-------------------------------------------------------------
00007 
00008 #include <cctype>
00009 #include <iostream>
00010 
00011 namespace {
00012 
00013 bool eatwhitespace ( std::istream & is ) {
00014   // Will discard whitespace until it either encounters EOF or bad input
00015   // (in which case it will return false) or it hits a non-whitespace.  
00016   // Will put that non whitespace character back so that after this routine
00017   // returns true, is.get(c) should always work.
00018   // If eatwhitespace returns false, is will always be in a fail or bad state.
00019   char c;
00020   bool avail = false;   // avail stays false until we know there is a nonwhite
00021                         // character available.
00022   while ( is.get(c) ) {
00023     if ( !isspace(c) ) {
00024       is.putback(c);
00025       avail = true;
00026       break;
00027     }
00028   }
00029   return avail;
00030 }
00031 
00032 void fouledup() {
00033   std::cerr << "istream mysteriously lost a putback character!\n";
00034 }
00035 
00036 
00037 } // end of unnamed namespace
00038 
00039 
00040 namespace CLHEP  {
00041 
00042 void ZMinput3doubles ( std::istream & is, const char * type,
00043                         double & x, double & y, double & z ) {
00044 
00045 // Accepted formats are 
00046 // x y z
00047 // x, y, z (each comma is optional, and whitespace ignored if comma present)
00048 // ( x, y, z ) (commas optional)
00049 
00050   char c;
00051   bool parenthesis = false;
00052 
00053   if ( !eatwhitespace(is) ) {
00054     std::cerr << "istream ended before trying to input " << type << "\n";
00055     return;
00056   }
00057 
00058   if ( !is.get(c) ) { fouledup(); return; }
00059   if ( c == '(' ) {
00060     parenthesis = true;
00061     if ( !eatwhitespace(is) ) {
00062       std::cerr << "istream ended after ( trying to input " << type << "\n";
00063       return;
00064     }
00065   } else {
00066     is.putback(c);
00067   }  
00068 
00069   // At this point, parenthesis or not, the next item read is supposed to
00070   // be the number x.
00071 
00072   if (!(is >> x)) {
00073     std::cerr << "Could not read first value in input of " << type << "\n";
00074     return;
00075   }
00076 
00077   if ( !eatwhitespace(is) ) {
00078     std::cerr << "istream ended before second value of " << type << "\n";
00079     return;
00080   } 
00081 
00082   if ( !is.get(c) ) { fouledup(); return; }
00083   if ( c == ',' ) {
00084     if ( !eatwhitespace(is) ) {
00085       std::cerr << "istream ended ater one value and comma in " 
00086                                                         << type << "\n";
00087       return;
00088     }
00089   } else {
00090     is.putback(c);
00091   }
00092 
00093   // At this point, comma or not, the next item read is supposed to
00094   // be the number y.
00095 
00096   if (!(is >> y)) {
00097     std::cerr << "Could not read second value in input of " << type << "\n";
00098     return;
00099   }
00100 
00101   if ( !eatwhitespace(is) ) {
00102     std::cerr << "istream ended before third value of " << type << "\n";
00103     return;
00104   } 
00105 
00106   if ( !is.get(c) ) { fouledup(); return; }
00107   if ( c == ',' ) {
00108     if ( !eatwhitespace(is) ) {
00109       std::cerr << "istream ended ater two values and comma in " 
00110                                                         << type << "\n";
00111       return;
00112     }
00113   } else {
00114     is.putback(c);
00115   }
00116 
00117   // At this point, comma or not, the next item read is supposed to
00118   // be the number z.
00119 
00120   if (!(is >> z)) {
00121     std::cerr << "Could not read third value in input of " << type << "\n";
00122     return;
00123   }
00124 
00125   // Finally, check for the closing parenthesis if there was an open paren.
00126 
00127   if (parenthesis) {
00128     if ( !eatwhitespace(is) ) {
00129       std::cerr << "No closing parenthesis in input of " << type << "\n";
00130       return;
00131     } 
00132     if ( !is.get(c) ) { fouledup(); return; }
00133     if ( c != ')' ) {
00134       std::cerr << "Missing closing parenthesis in input of " 
00135                                                         << type << "\n";
00136       // Now a trick to do (as nearly as we can) what 
00137       // is.putback(c); is.setstate(std::ios_base::failbit); 
00138       // would do (because using ios_base will confuse old CLHEP compilers):
00139       if ( isdigit(c) || (c=='-') || (c=='+') ) {
00140         is.putback('@');
00141       } else {
00142         is.putback('c');
00143       }
00144       int m;
00145       is >> m;  // This fails, leaving the state bad, and the istream
00146                 // otherwise unchanged, except if the next char might
00147                 // have started a valid int, it turns to @
00148       return;
00149     }
00150   }
00151 
00152   return;
00153 
00154 }
00155 
00156 void ZMinputAxisAngle ( std::istream & is, 
00157                         double & x, double & y, double & z, 
00158                         double & delta ) {
00159 // Accepted formats are 
00160 // parenthesis optional, then
00161 // any acceptable format for a Hep3Vector, then
00162 // optional comma, then
00163 // delta, then
00164 // close parenthesis if opened at start.
00165 //
00166 // But if there is an open parenthesis, it must be for the overall
00167 // object.  That is, if the axis has parentheses, the form must be 
00168 // ( (x,y,z) , delta ) 
00169 
00170   char c;
00171   bool parenthesis = false;
00172 
00173   if ( !eatwhitespace(is) ) {
00174     std::cerr << "istream ended before trying to input AxisAngle \n";
00175     return;
00176   }
00177 
00178   if ( !is.get(c) ) { fouledup(); return; }
00179   if ( c == '(' ) {
00180     parenthesis = true;
00181     if ( !eatwhitespace(is) ) {
00182       std::cerr << "istream ended after ( trying to input AxisAngle \n";
00183       return;
00184     }
00185   } else {
00186     is.putback(c);
00187   }  
00188 
00189   // At this point, parenthesis or not, the next item read is supposed to
00190   // be a valid Hep3Vector axis.
00191 
00192   ZMinput3doubles ( is, "axis of AxisAngle", x, y, z );
00193   if (!is) return;
00194 
00195   if ( !eatwhitespace(is) ) {
00196     std::cerr << "istream ended before delta of AxisAngle \n";
00197     return;
00198   } 
00199 
00200   if ( !is.get(c) ) { fouledup(); return; }
00201   if ( c == ',' ) {
00202     if ( !eatwhitespace(is) ) {
00203       std::cerr << "istream ended ater axis and comma in AxisAngle \n"; 
00204       return;
00205     }
00206   } else {
00207     is.putback(c);
00208   }
00209 
00210   // At this point, comma or not, the next item read is supposed to
00211   // be the number delta.
00212 
00213   if (!(is >> delta)) {
00214     std::cerr << "Could not delta value in input of AxisAngle \n";
00215     return;
00216   }
00217 
00218   // Finally, check for the closing parenthesis if there was an open paren.
00219 
00220   if (parenthesis) {
00221     if ( !eatwhitespace(is) ) {
00222       std::cerr << "No closing parenthesis in input of AxisAngle \n";
00223       return;
00224     } 
00225     if ( !is.get(c) ) { fouledup(); return; }
00226     if ( c != ')' ) {
00227       std::cerr << "Missing closing parenthesis in input of AxisAngle \n";
00228       if ( isdigit(c) || (c=='-') || (c=='+') ) {
00229         is.putback('@');
00230       } else {
00231         is.putback('c');
00232       }
00233       int m;
00234       is >> m;  // This fails, leaving the state bad.
00235       return;
00236     }
00237   }
00238 
00239   return;
00240 
00241 }
00242 
00243 void ZMinput2doubles ( std::istream & is, const char * type,
00244                         double & x, double & y ) {
00245 
00246 // Accepted formats are 
00247 // x y 
00248 // x, y (comma is optional, and whitespace ignored if comma present)
00249 // ( x, y ) (comma optional)
00250 
00251   char c;
00252   bool parenthesis = false;
00253 
00254   if ( !eatwhitespace(is) ) {
00255     std::cerr << "istream ended before trying to input " << type << "\n";
00256     return;
00257   }
00258 
00259   if ( !is.get(c) ) { fouledup(); return; }
00260   if ( c == '(' ) {
00261     parenthesis = true;
00262     if ( !eatwhitespace(is) ) {
00263       std::cerr << "istream ended after ( trying to input " << type << "\n";
00264       return;
00265     }
00266   } else {
00267     is.putback(c);
00268   }  
00269 
00270   // At this point, parenthesis or not, the next item read is supposed to
00271   // be the number x.
00272 
00273   if (!(is >> x)) {
00274     std::cerr << "Could not read first value in input of " << type << "\n";
00275     return;
00276   }
00277 
00278   if ( !eatwhitespace(is) ) {
00279     std::cerr << "istream ended before second value of " << type << "\n";
00280     return;
00281   } 
00282 
00283   if ( !is.get(c) ) { fouledup(); return; }
00284   if ( c == ',' ) {
00285     if ( !eatwhitespace(is) ) {
00286       std::cerr << "istream ended ater one value and comma in " 
00287                                                         << type << "\n";
00288       return;
00289     }
00290   } else {
00291     is.putback(c);
00292   }
00293 
00294   // At this point, comma or not, the next item read is supposed to
00295   // be the number y.
00296 
00297   if (!(is >> y)) {
00298     std::cerr << "Could not read second value in input of " << type << "\n";
00299     return;
00300   }
00301 
00302   // Finally, check for the closing parenthesis if there was an open paren.
00303 
00304   if (parenthesis) {
00305     if ( !eatwhitespace(is) ) {
00306       std::cerr << "No closing parenthesis in input of " << type << "\n";
00307       return;
00308     } 
00309     if ( !is.get(c) ) { fouledup(); return; }
00310     if ( c != ')' ) {
00311       std::cerr << "Missing closing parenthesis in input of " 
00312                                                         << type << "\n";
00313       // Now a trick to do (as nearly as we can) what 
00314       // is.putback(c); is.setstate(std::ios_base::failbit); 
00315       // would do (because using ios_base will confuse old CLHEP compilers):
00316       if ( isdigit(c) || (c=='-') || (c=='+') ) {
00317         is.putback('@');
00318       } else {
00319         is.putback('c');
00320       }
00321       int m;
00322       is >> m;  // This fails, leaving the state bad, and the istream
00323                 // otherwise unchanged, except if the next char might
00324                 // have started a valid int, it turns to @
00325       return;
00326     }
00327   }
00328 
00329   return;
00330 
00331 }
00332 
00333 }  // namespace CLHEP

Generated on Mon May 27 17:50:37 2013 for Geant4 by  doxygen 1.4.7