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