Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ZMinput.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 // ---------------------------------------------------------------------------
3 //
4 // This file is a part of the CLHEP - a Class Library for High Energy Physics.
5 //
6 //-------------------------------------------------------------
7 
8 #include <cctype>
9 #include <iostream>
10 
11 namespace {
12 
13 bool eatwhitespace ( std::istream & is ) {
14  // Will discard whitespace until it either encounters EOF or bad input
15  // (in which case it will return false) or it hits a non-whitespace.
16  // Will put that non whitespace character back so that after this routine
17  // returns true, is.get(c) should always work.
18  // If eatwhitespace returns false, is will always be in a fail or bad state.
19  char c;
20  bool avail = false; // avail stays false until we know there is a nonwhite
21  // character available.
22  while ( is.get(c) ) {
23  if ( !isspace(c) ) {
24  is.putback(c);
25  avail = true;
26  break;
27  }
28  }
29  return avail;
30 }
31 
32 void fouledup() {
33  std::cerr << "istream mysteriously lost a putback character!\n";
34 }
35 
36 
37 } // end of unnamed namespace
38 
39 
40 namespace CLHEP {
41 
42 void ZMinput3doubles ( std::istream & is, const char * type,
43  double & x, double & y, double & z ) {
44 
45 // Accepted formats are
46 // x y z
47 // x, y, z (each comma is optional, and whitespace ignored if comma present)
48 // ( x, y, z ) (commas optional)
49 
50  char c;
51  bool parenthesis = false;
52 
53  if ( !eatwhitespace(is) ) {
54  std::cerr << "istream ended before trying to input " << type << "\n";
55  return;
56  }
57 
58  if ( !is.get(c) ) { fouledup(); return; }
59  if ( c == '(' ) {
60  parenthesis = true;
61  if ( !eatwhitespace(is) ) {
62  std::cerr << "istream ended after ( trying to input " << type << "\n";
63  return;
64  }
65  } else {
66  is.putback(c);
67  }
68 
69  // At this point, parenthesis or not, the next item read is supposed to
70  // be the number x.
71 
72  if (!(is >> x)) {
73  std::cerr << "Could not read first value in input of " << type << "\n";
74  return;
75  }
76 
77  if ( !eatwhitespace(is) ) {
78  std::cerr << "istream ended before second value of " << type << "\n";
79  return;
80  }
81 
82  if ( !is.get(c) ) { fouledup(); return; }
83  if ( c == ',' ) {
84  if ( !eatwhitespace(is) ) {
85  std::cerr << "istream ended ater one value and comma in "
86  << type << "\n";
87  return;
88  }
89  } else {
90  is.putback(c);
91  }
92 
93  // At this point, comma or not, the next item read is supposed to
94  // be the number y.
95 
96  if (!(is >> y)) {
97  std::cerr << "Could not read second value in input of " << type << "\n";
98  return;
99  }
100 
101  if ( !eatwhitespace(is) ) {
102  std::cerr << "istream ended before third value of " << type << "\n";
103  return;
104  }
105 
106  if ( !is.get(c) ) { fouledup(); return; }
107  if ( c == ',' ) {
108  if ( !eatwhitespace(is) ) {
109  std::cerr << "istream ended ater two values and comma in "
110  << type << "\n";
111  return;
112  }
113  } else {
114  is.putback(c);
115  }
116 
117  // At this point, comma or not, the next item read is supposed to
118  // be the number z.
119 
120  if (!(is >> z)) {
121  std::cerr << "Could not read third value in input of " << type << "\n";
122  return;
123  }
124 
125  // Finally, check for the closing parenthesis if there was an open paren.
126 
127  if (parenthesis) {
128  if ( !eatwhitespace(is) ) {
129  std::cerr << "No closing parenthesis in input of " << type << "\n";
130  return;
131  }
132  if ( !is.get(c) ) { fouledup(); return; }
133  if ( c != ')' ) {
134  std::cerr << "Missing closing parenthesis in input of "
135  << type << "\n";
136  // Now a trick to do (as nearly as we can) what
137  // is.putback(c); is.setstate(std::ios_base::failbit);
138  // would do (because using ios_base will confuse old CLHEP compilers):
139  if ( isdigit(c) || (c=='-') || (c=='+') ) {
140  is.putback('@');
141  } else {
142  is.putback('c');
143  }
144  int m;
145  is >> m; // This fails, leaving the state bad, and the istream
146  // otherwise unchanged, except if the next char might
147  // have started a valid int, it turns to @
148  return;
149  }
150  }
151 
152  return;
153 
154 }
155 
156 void ZMinputAxisAngle ( std::istream & is,
157  double & x, double & y, double & z,
158  double & delta ) {
159 // Accepted formats are
160 // parenthesis optional, then
161 // any acceptable format for a Hep3Vector, then
162 // optional comma, then
163 // delta, then
164 // close parenthesis if opened at start.
165 //
166 // But if there is an open parenthesis, it must be for the overall
167 // object. That is, if the axis has parentheses, the form must be
168 // ( (x,y,z) , delta )
169 
170  char c;
171  bool parenthesis = false;
172 
173  if ( !eatwhitespace(is) ) {
174  std::cerr << "istream ended before trying to input AxisAngle \n";
175  return;
176  }
177 
178  if ( !is.get(c) ) { fouledup(); return; }
179  if ( c == '(' ) {
180  parenthesis = true;
181  if ( !eatwhitespace(is) ) {
182  std::cerr << "istream ended after ( trying to input AxisAngle \n";
183  return;
184  }
185  } else {
186  is.putback(c);
187  }
188 
189  // At this point, parenthesis or not, the next item read is supposed to
190  // be a valid Hep3Vector axis.
191 
192  ZMinput3doubles ( is, "axis of AxisAngle", x, y, z );
193  if (!is) return;
194 
195  if ( !eatwhitespace(is) ) {
196  std::cerr << "istream ended before delta of AxisAngle \n";
197  return;
198  }
199 
200  if ( !is.get(c) ) { fouledup(); return; }
201  if ( c == ',' ) {
202  if ( !eatwhitespace(is) ) {
203  std::cerr << "istream ended ater axis and comma in AxisAngle \n";
204  return;
205  }
206  } else {
207  is.putback(c);
208  }
209 
210  // At this point, comma or not, the next item read is supposed to
211  // be the number delta.
212 
213  if (!(is >> delta)) {
214  std::cerr << "Could not delta value in input of AxisAngle \n";
215  return;
216  }
217 
218  // Finally, check for the closing parenthesis if there was an open paren.
219 
220  if (parenthesis) {
221  if ( !eatwhitespace(is) ) {
222  std::cerr << "No closing parenthesis in input of AxisAngle \n";
223  return;
224  }
225  if ( !is.get(c) ) { fouledup(); return; }
226  if ( c != ')' ) {
227  std::cerr << "Missing closing parenthesis in input of AxisAngle \n";
228  if ( isdigit(c) || (c=='-') || (c=='+') ) {
229  is.putback('@');
230  } else {
231  is.putback('c');
232  }
233  int m;
234  is >> m; // This fails, leaving the state bad.
235  return;
236  }
237  }
238 
239  return;
240 
241 }
242 
243 void ZMinput2doubles ( std::istream & is, const char * type,
244  double & x, double & y ) {
245 
246 // Accepted formats are
247 // x y
248 // x, y (comma is optional, and whitespace ignored if comma present)
249 // ( x, y ) (comma optional)
250 
251  char c;
252  bool parenthesis = false;
253 
254  if ( !eatwhitespace(is) ) {
255  std::cerr << "istream ended before trying to input " << type << "\n";
256  return;
257  }
258 
259  if ( !is.get(c) ) { fouledup(); return; }
260  if ( c == '(' ) {
261  parenthesis = true;
262  if ( !eatwhitespace(is) ) {
263  std::cerr << "istream ended after ( trying to input " << type << "\n";
264  return;
265  }
266  } else {
267  is.putback(c);
268  }
269 
270  // At this point, parenthesis or not, the next item read is supposed to
271  // be the number x.
272 
273  if (!(is >> x)) {
274  std::cerr << "Could not read first value in input of " << type << "\n";
275  return;
276  }
277 
278  if ( !eatwhitespace(is) ) {
279  std::cerr << "istream ended before second value of " << type << "\n";
280  return;
281  }
282 
283  if ( !is.get(c) ) { fouledup(); return; }
284  if ( c == ',' ) {
285  if ( !eatwhitespace(is) ) {
286  std::cerr << "istream ended ater one value and comma in "
287  << type << "\n";
288  return;
289  }
290  } else {
291  is.putback(c);
292  }
293 
294  // At this point, comma or not, the next item read is supposed to
295  // be the number y.
296 
297  if (!(is >> y)) {
298  std::cerr << "Could not read second value in input of " << type << "\n";
299  return;
300  }
301 
302  // Finally, check for the closing parenthesis if there was an open paren.
303 
304  if (parenthesis) {
305  if ( !eatwhitespace(is) ) {
306  std::cerr << "No closing parenthesis in input of " << type << "\n";
307  return;
308  }
309  if ( !is.get(c) ) { fouledup(); return; }
310  if ( c != ')' ) {
311  std::cerr << "Missing closing parenthesis in input of "
312  << type << "\n";
313  // Now a trick to do (as nearly as we can) what
314  // is.putback(c); is.setstate(std::ios_base::failbit);
315  // would do (because using ios_base will confuse old CLHEP compilers):
316  if ( isdigit(c) || (c=='-') || (c=='+') ) {
317  is.putback('@');
318  } else {
319  is.putback('c');
320  }
321  int m;
322  is >> m; // This fails, leaving the state bad, and the istream
323  // otherwise unchanged, except if the next char might
324  // have started a valid int, it turns to @
325  return;
326  }
327  }
328 
329  return;
330 
331 }
332 
333 } // namespace CLHEP