Belle II Software  release-06-02-00
VxdID.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <vxd/dataobjects/VxdID.h>
10 #include <sstream>
11 
12 using namespace std;
13 
14 namespace Belle2 {
20  namespace {
26  int getPart(istream& in)
27  {
28  if (!in.eof()) {
29  //Get next char, if it is a dot, ignore it and get the next one
30  int next = in.get();
31  if (next == '.') next = in.get();
32  //If it is a wildcard we return 0 as id, otherwise we put it back in the stream
33  if (next == '*' or in.eof()) {
34  return 0;
35  } else {
36  in.unget();
37  }
38  //If it is the segment separator, we assume the remaining parts to be missing, so return 0
39  if (next == '#') return 0;
40 
41  //Now get the actual value out of the stream. If this fails something is wrong and it is not
42  //a valid id
43  int value(0);
44  in >> value;
45  if (in.fail() && !in.eof()) {
46  throw runtime_error("Failed to parse Number");
47  }
48  return value;
49  }
50  return 0;
51  }
52  }
53 
54  VxdID::VxdID(const std::string& sensor)
55  {
56  //We parse the Id from string, so set it to 0 first
57  m_id.id = 0;
58  //create a stream from the string
59  istringstream in(sensor);
60  try {
61  //Get all the parts
62  m_id.parts.layer = getPart(in);
63  m_id.parts.ladder = getPart(in);
64  m_id.parts.sensor = getPart(in);
65  //Check if we also have a segment specified, if so get it
66  if (in.peek() == '#') {
67  in.get();
68  m_id.parts.segment = getPart(in);
69  }
70  } catch (runtime_error&) {
71  //Something went wrong parsing the parts
72  m_id.id = 0;
73  throw invalid_argument("Could not parse VxdID: '" + sensor + "'");
74  }
75  //There is stuff left we also throw an exception as we cannot warn the user
76  //without the logging system
77  if (!in.eof()) {
78  string rest;
79  //Get the remainder: get everything in the stream until the next NULL
80  //character which should only occur at the end of the string.
81  getline(in, rest, '\0');
82  throw invalid_argument("Trailing characters after VxdID " + (string)*this + ": '" + rest + "'");
83  }
84  }
85 
86  VxdID::operator string() const
87  {
88  stringstream out;
89  if (m_id.parts.layer) {
90  out << m_id.parts.layer;
91  } else {
92  out << "*";
93  }
94  if (m_id.parts.ladder || m_id.parts.sensor) {
95  out << ".";
96  if (m_id.parts.ladder) {
97  out << m_id.parts.ladder;
98  } else {
99  out << "*";
100  }
101  }
102  if (m_id.parts.sensor) {
103  out << "." << m_id.parts.sensor;
104  }
105  if (m_id.parts.segment) {
106  out << "#" << m_id.parts.segment;
107  }
108  return out.str();
109  }
110 
111  std::ostream& operator<<(std::ostream& out, const VxdID& id)
112  {
113  out << ((string)id);
114  return out;
115  }
116 
118 }
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
Abstract base class for different kinds of events.