7 #include "Alignment/Geners/interface/IOException.hh"
9 #include "Alignment/Geners/interface/ClassId.hh"
10 #include "Alignment/Geners/interface/binaryIO.hh"
11 #include "Alignment/Geners/interface/IOException.hh"
16 void ClassId::setVersion(
const unsigned newVersion)
18 if (version_ != newVersion)
20 version_ = newVersion;
23 const std::size_t lastOpen = id_.find_last_of(
'(');
24 assert(lastOpen != std::string::npos);
26 std::ostringstream os;
27 os << id_.substr(0, lastOpen) <<
'(' << version_ <<
')';
34 void ClassId::ensureSameId(
const ClassId&
id)
const
37 throw gs::IOInvalidArgument(
38 "In gs::ClassId::ensureSameId: reference id is not valid");
40 throw gs::IOInvalidArgument(
41 "In gs::ClassId::ensureSameId: argument id is not valid");
44 std::ostringstream os;
45 os <<
"In gs::ClassId::ensureSameId: expected \""
46 << id_ <<
"\", got \"" <<
id.id_ <<
"\"";
47 throw gs::IOInvalidArgument(os.str());
51 void ClassId::ensureSameName(
const ClassId&
id)
const
54 throw gs::IOInvalidArgument(
55 "In gs::ClassId::ensureSameName: reference id is not valid");
57 throw gs::IOInvalidArgument(
58 "In gs::ClassId::ensureSameName: argument id is not valid");
59 if (name_ !=
id.name_)
61 std::ostringstream os;
62 os <<
"In gs::ClassId::ensureSameName: expected class name \""
63 << name_ <<
"\", got \"" <<
id.name_ <<
"\"";
64 throw gs::IOInvalidArgument(os.str());
68 void ClassId::ensureSameVersion(
const ClassId&
id)
const
71 throw gs::IOInvalidArgument(
72 "In gs::ClassId::ensureSameVersion: reference id is not valid");
74 throw gs::IOInvalidArgument(
75 "In gs::ClassId::ensureSameVersion: argument id is not valid");
76 if (version_ !=
id.version_)
78 std::ostringstream os;
79 os <<
"In gs::ClassId::ensureSameVersion: expected version "
80 << version_ <<
" for class " <<
id.name_
81 <<
", got " <<
id.version_;
82 throw gs::IOInvalidArgument(os.str());
86 void ClassId::ensureVersionInRange(
const unsigned vmin,
87 const unsigned vmax)
const
90 throw gs::IOInvalidArgument(
91 "In gs::ClassId::ensureVersionInRange: id is not valid");
92 if (version_ < vmin || version_ > vmax)
94 std::ostringstream os;
95 os <<
"In gs::ClassId::ensureVersionInRange: expected version"
96 <<
" number for class " << name_ <<
" to be in range ["
97 << vmin <<
", " << vmax <<
"], got " << version_;
98 throw gs::IOInvalidArgument(os.str());
102 bool ClassId::validatePrefix(
const char*
prefix)
107 const unsigned len = strlen(prefix);
114 bool inVersion =
false;
116 for (
unsigned i=0;
i<len; ++
i)
118 if (prefix[
i] ==
'(')
122 if (inVersion ||
i == 0)
127 else if (prefix[
i] ==
')')
137 unsigned long dummy = strtoul(prefix+vstart, &endptr, 10);
139 if (endptr != prefix+
i)
150 void ClassId::initialize(
const char* prefix,
const unsigned version,
153 std::ostringstream os;
154 if (!validatePrefix(prefix))
157 os <<
"In gs::ClassId::initialize: bad class name prefix \""
158 << prefix <<
"\". Check for problematic parentheses.";
160 os <<
"In gs::ClassId::initialize: NULL class name prefix.";
161 throw gs::IOInvalidArgument(os.str());
163 os << prefix <<
'(' << version <<
')';
173 bool ClassId::makeName()
176 char* buf = localbuf;
177 const unsigned idLen = id_.size();
179 buf =
new char[idLen+1U];
180 const char* from = id_.data();
181 bool inVersion =
false;
183 for (
unsigned ifrom=0; ifrom < idLen; ++ifrom)
185 if (from[ifrom] ==
'(')
189 if (buf != localbuf)
delete [] buf;
194 else if (from[ifrom] ==
')')
198 if (buf != localbuf)
delete [] buf;
204 buf[ito++] = from[ifrom];
208 if (buf != localbuf)
delete [] buf;
213 if (buf != localbuf)
delete [] buf;
218 bool ClassId::makeVersion()
220 bool correct =
false;
221 const unsigned ns = id_.size();
222 const char*
const buf = id_.data();
223 const char* sep = buf + (ns - 1U);
233 const char* closingBrace = sep;
234 for (; sep != buf; --sep)
240 version_ = strtoul(sep + 1, &endptr, 10);
241 if (endptr > sep + 1 && endptr == closingBrace)
251 if (!(!id_.empty() && makeName() && makeVersion()))
253 std::ostringstream os;
254 os <<
"In gs::ClassId::ClassId(const std::string&): "
255 <<
"invalid input id string \"" << id_ <<
"\"";
256 throw gs::IOInvalidArgument(os.str());
260 ClassId::ClassId(std::istream&
in,
int)
263 if (in.fail())
throw IOReadFailure(
264 "In gs::ClassId::ClassId(std::istream&, int): "
265 "input stream failure");
267 if (!(!id_.empty() && makeName() && makeVersion()))
269 std::ostringstream os;
270 os <<
"In gs::ClassId::ClassId(std::istream&, int): "
271 <<
"read invalid id string \"" << id_ <<
"\"";
272 throw IOInvalidData(os.str());
283 : name_(
""), id_(
"(0)"), version_(0U), isPtr_(
false)
287 ClassId ClassId::invalidId()
293 bool ClassId::isTemplate()
const
295 const std::size_t leftBrak = id_.find(
'<');
296 const std::size_t rightBrak = id_.rfind(
'>');
297 return leftBrak != std::string::npos &&
298 rightBrak != std::string::npos &&
299 leftBrak < rightBrak;
302 void ClassId::templateParameters(
303 std::vector<std::vector<ClassId> >* params)
const
307 const std::size_t leftBrak = id_.find(
'<');
308 const std::size_t rightBrak = id_.rfind(
'>');
309 if (leftBrak != std::string::npos &&
310 rightBrak != std::string::npos &&
311 leftBrak < rightBrak)
314 unsigned ncommas = 0;
316 for (std::size_t pos = leftBrak+1; pos<rightBrak; ++pos)
318 const char c = id_[pos];
319 if (c ==
'<') ++nbrackets;
320 else if (c ==
'>') --nbrackets;
321 else if (c ==
',' && nbrackets == 0)
328 std::ostringstream os;
329 os <<
"In gs::ClassId::templateParameters: "
330 <<
"unbalanced angle brackets in the "
331 <<
"template id \"" << id_ <<
"\"";
332 throw gs::IOInvalidArgument(os.str());
336 params->resize(ncommas + 1);
337 for (
unsigned i=0;
i<=ncommas; ++
i)
338 (*params)[
i].reserve(1);
343 std::size_t
begin = leftBrak + 1;
344 for (std::size_t pos = begin; pos<rightBrak; ++pos)
346 const char c = id_[pos];
347 if (c ==
'<') ++nbrackets;
348 else if (c ==
'>') --nbrackets;
349 else if (c ==
',' && nbrackets == 0)
351 while (isspace(id_[begin])) ++
begin;
352 std::size_t
end = pos - 1;
353 while (isspace(id_[end])) --
end;
355 (*params)[ncommas].push_back(
356 ClassId(id_.substr(begin, end - begin)));
361 while (isspace(id_[begin])) ++begin;
362 std::size_t
end = rightBrak - 1;
363 while (isspace(id_[end])) --end;
365 (*params)[ncommas].push_back(
366 ClassId(id_.substr(begin, end - begin)));