ATLAS Offline Software
Loading...
Searching...
No Matches
ObjectMetadata.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6// Boost include(s):
7#include <boost/tokenizer.hpp>
8
9// Gaudi/Athena include(s):
10#include "GaudiKernel/System.h"
12
13// Local include(s):
15
17namespace {
18
20
30 bool isPrimitive( const std::type_info& ti ) {
31
32 if( ( ti == typeid( char* ) ) ||
33 ( ti == typeid( char ) ) ||
34 ( ti == typeid( unsigned char ) ) ||
35 ( ti == typeid( short ) ) ||
36 ( ti == typeid( unsigned short ) ) ||
37 ( ti == typeid( int ) ) ||
38 ( ti == typeid( unsigned int ) ) ||
39 ( ti == typeid( float ) ) ||
40 ( ti == typeid( double ) ) ||
41 ( ti == typeid( long long ) ) ||
42 ( ti == typeid( unsigned long long ) ) ||
43 ( ti == typeid( bool ) ) ) {
44
45 return true;
46 }
47
48 return false;
49 }
50
51} // namespace
52
53namespace D3PD {
54
55 // Set the value of the constant(s):
57 const char* const ObjectMetadata::STRING_SEPARATOR = "@";
58 const unsigned int ObjectMetadata::SERIALIZER_VERSION = 1;
60
62 : m_variables(), m_name( "" ), m_prefix( "" ),
63 m_container( false ) {
64
65 }
66
68 : m_variables( parent.m_variables ), m_name( parent.m_name ),
69 m_prefix( parent.m_prefix ), m_container( parent.m_container ) {
70
71 }
72
74 {
75 if (&parent != this) {
76 m_variables = parent.m_variables;
77 m_name = parent.m_name;
78 m_prefix = parent.m_prefix;
79 m_container = parent.m_container;
80 }
81
82 return *this;
83 }
84
86
87 return ( ( name() == rhs.name() ) && ( prefix() == rhs.prefix() ) &&
88 ( container() == rhs.container() ) );
89 }
90
91 bool ObjectMetadata::operator< ( const ObjectMetadata& rhs ) const {
92
93 if( prefix() != rhs.prefix() ) {
94 return ( prefix() < rhs.prefix() );
95 } else if( name() != rhs.name() ) {
96 return ( name() < rhs.name() );
97 } else {
98 return ( container() < rhs.container() );
99 }
100 }
101
109 StatusCode ObjectMetadata::addVariable( const std::string& name,
110 const std::type_info& ti,
111 void*& /*ptr*/,
112 const std::string& docstring,
113 const void* /*defval*/ ) {
114
115 // Check that the variable has the correct prefix:
116 if( m_prefix != "" &&
117 !name.starts_with( m_prefix) )
118 {
119 REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "ObjectMetadata" )
120 << "Specified variable name (" << name << ") doesn't have the "
121 << "expected prefix (" << m_prefix << ")";
122 return StatusCode::RECOVERABLE;
123 }
124
125 // Create a new variable:
126 Variable var;
127
128 // Remove the prefix from the variable name:
129 var.setName( name.substr( m_prefix.size(), name.npos ) );
130
131 // Check if it's already amongst the existing variables:
132 if( m_variables.find( var ) != m_variables.end() ) {
133 return StatusCode::SUCCESS;
134 }
135
136 // Set the type of the variable:
137 var.setType( System::typeinfoName( ti.name() ) );
138
139 // Set whether the variable is a primitive:
140 var.setPrimitive( isPrimitive( ti ) );
141
142 // Set the documentation string for the variable:
143 var.setDoc( docstring );
144
145 // Remember the variable:
146 m_variables.insert( std::move(var) );
147
148 return StatusCode::SUCCESS;
149 }
150
156 StatusCode
157 ObjectMetadata::addDimensionedVariable( const std::string& /*name*/,
158 const std::type_info& /*ti*/,
159 void*& /*ptr*/,
160 const std::string& /*dim*/,
161 const std::string& /*docstring*/,
162 const void* /*defval*/ ) {
163
164 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
165 << "addDimensionedVariable(...) not implemented";
166
167 return StatusCode::FAILURE;
168 }
169
170 const std::string& ObjectMetadata::name() const {
171
172 return m_name;
173 }
174
175 void ObjectMetadata::setName( const std::string& name ) {
176
177 m_name = name;
178 return;
179 }
180
191 std::string ObjectMetadata::metadataName ATLAS_NOT_THREAD_SAFE () const {
192
193 // Variable used to give names to unnamed D3PDObject-s
194 static size_t objectCounter = 0;
195 std::string name = m_name;
196 if (name.empty()) {
197 ++objectCounter;
198 name = "D3PDObject" + std::to_string( objectCounter );
199 }
200 return name + "_" + genSuffix (name, RANDOM_NAME_POSTFIX_LENGTH);
201 }
202
213 std::string ObjectMetadata::objectName( const std::string& metaName ) {
214
215 return metaName.substr( 0, metaName.size() -
217 }
218
219 const std::string& ObjectMetadata::prefix() const {
220
221 return m_prefix;
222 }
223
224 void ObjectMetadata::setPrefix( const std::string& prefix ) {
225
227 return;
228 }
229
231
232 return m_container;
233 }
234
236
238 return;
239 }
240
249 std::string ObjectMetadata::toString() const {
250
251 // Save the simple part of the information
252 std::string result =
253 std::to_string( SERIALIZER_VERSION ) +
255 STRING_SEPARATOR + ( m_container ? "1" : "0" );
256
257 // Save the serialized version of all the variables:
258 std::set< Variable >::const_iterator itr = m_variables.begin();
259 std::set< Variable >::const_iterator end = m_variables.end();
260 for( ; itr != end; ++itr ) {
261 result += STRING_SEPARATOR + itr->toString();
262 }
263
264 return result;
265 }
266
276 StatusCode ObjectMetadata::read( const std::string& data ) {
277
278 //
279 // Tokenize the string using Boost:
280 //
281 boost::char_separator< char > separator( STRING_SEPARATOR, "",
282 boost::keep_empty_tokens );
283 boost::tokenizer< boost::char_separator< char > > tokens( data,
284 separator );
285 boost::tokenizer< boost::char_separator< char > >::const_iterator itr = tokens.begin();
286 boost::tokenizer< boost::char_separator< char > >::const_iterator end = tokens.end();
287
288 // Check that we didn't reach the last token yet:
289 if( itr == end ) {
290 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
291 << "The received data can not be parsed successfully: "
292 << data;
293 return StatusCode::FAILURE;
294 }
295
296 // Check that the metadata was saved using the same version of the
297 // serializer code. Later on we might want to introduce backward
298 // compatibility, but for now this simple check should be enough.
299 if( atoi(itr->c_str()) != SERIALIZER_VERSION ) {
300 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
301 << "Version mismatch! The metadata was saved with a different "
302 << "serialization version (" << *itr << ") than the code used ("
303 << SERIALIZER_VERSION << ")";
304 return StatusCode::FAILURE;
305 }
306
307 ++itr;
308
309 // Check that we didn't reach the last token yet:
310 if( itr == end ) {
311 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
312 << "The received data can not be parsed successfully: "
313 << data;
314 return StatusCode::FAILURE;
315 }
316
317 // Extract the prefix from the metadata:
318 m_prefix = *itr; ++itr;
319
320 // Check that we didn't reach the last token yet:
321 if( itr == end ) {
322 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
323 << "The received data can not be parsed successfully: "
324 << data;
325 return StatusCode::FAILURE;
326 }
327
328 // Extract whether this is a container that the variables describe:
329 if( *itr == "0" ) {
330 m_container = false;
331 } else if( *itr == "1" ) {
332 m_container = true;
333 } else {
334 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
335 << "The received data can not be parsed successfully: "
336 << data;
337 return StatusCode::FAILURE;
338 }
339
340 ++itr;
341
342 // Finally, let's extract all the variable metadata:
343 for( ; itr != end; ++itr ) {
344 Variable var;
345 CHECK( var.read( *itr ) );
346 m_variables.insert( std::move(var) );
347 }
348
349 return StatusCode::SUCCESS;
350 }
351
353
354 // Clear/reset all the variables:
355 m_variables.clear();
356 m_name = "";
357 m_prefix = "";
358 m_container = false;
359
360 return;
361 }
362
364
365 return this->merge( obj );
366 }
367
376
377 // Only objects with the same "name" should be merged:
378 if( name() != obj.name() ) {
379 REPORT_MESSAGE_WITH_CONTEXT( MSG::WARNING, "ObjectMetadata" )
380 << "Can't merge object with name \"" << obj.name()
381 << "\" into another object with name \"" << name() << "\"";
382 return *this;
383 }
384
385 // Now merge all the variable definitions:
386 std::set< Variable >::const_iterator itr = obj.variables().begin();
387 std::set< Variable >::const_iterator end = obj.variables().end();
388 for( ; itr != end; ++itr ) {
389 m_variables.insert( *itr );
390 }
391
392 return *this;
393 }
394
406 std::string ObjectMetadata::genSuffix ATLAS_NOT_THREAD_SAFE (const std::string& name,
407 size_t length)
408 {
409
410 // Count of the number of times a given name was used,
411 // in order to assign them a unique suffix.
412 static std::unordered_map<std::string, size_t> namecount;
413
414 const size_t count = ++namecount[name];
415 std::ostringstream os;
416 os << std::setw(length) << std::setprecision(length) << std::setfill('0')
417 << count;
418 return os.str();
419 }
420
421
423 : m_type( "" ), m_name( "" ), m_doc( "" ), m_primitive( true ) {
424
425 }
426
427 const std::string& ObjectMetadata::Variable::type() const {
428
429 return m_type;
430 }
431
432 const std::string& ObjectMetadata::Variable::name() const {
433
434 return m_name;
435 }
436
437 const std::string& ObjectMetadata::Variable::doc() const {
438
439 return m_doc;
440 }
441
443
444 return m_primitive;
445 }
446
447 void ObjectMetadata::Variable::setType( const std::string& type ) {
448
449 m_type = type;
450 return;
451 }
452
453 void ObjectMetadata::Variable::setName( const std::string& name ) {
454
455 m_name = name;
456 return;
457 }
458
459 void ObjectMetadata::Variable::setDoc( const std::string& doc ) {
460
461 m_doc = doc;
462 return;
463 }
464
466
468 return;
469 }
470
480
482 m_doc + STRING_SEPARATOR + ( m_primitive ? "1" : "0" );
483 }
484
495 StatusCode ObjectMetadata::Variable::read( const std::string& data ) {
496
497 //
498 // Tokenize the string using Boost:
499 //
500 boost::char_separator< char > separator( STRING_SEPARATOR, "",
501 boost::keep_empty_tokens );
502 boost::tokenizer< boost::char_separator< char > > tokens( data,
503 separator );
504 boost::tokenizer< boost::char_separator< char > >::const_iterator itr = tokens.begin();
505
506 // Check that we didn't reach the last token yet:
507 if( itr == tokens.end() ) {
508 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata::Variable" )
509 << "The received data can not be parsed successfully: "
510 << data;
511 return StatusCode::FAILURE;
512 }
513
514 // Extract the name of the variable:
515 m_name = *itr; ++itr;
516
517 // Check that we didn't reach the last token yet:
518 if( itr == tokens.end() ) {
519 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata::Variable" )
520 << "The received data can not be parsed successfully: "
521 << data;
522 return StatusCode::FAILURE;
523 }
524
525 // Extract the type of the variable:
526 m_type = *itr; ++itr;
527
528 // Check that we didn't reach the last token yet:
529 if( itr == tokens.end() ) {
530 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata::Variable" )
531 << "The received data can not be parsed successfully: "
532 << data;
533 return StatusCode::FAILURE;
534 }
535
536 // Extract the documentation string of the variable:
537 m_doc = *itr; ++itr;
538
539 // Check that we didn't reach the last token yet:
540 if( itr == tokens.end() ) {
541 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata::Variable" )
542 << "The received data can not be parsed successfully: "
543 << data;
544 return StatusCode::FAILURE;
545 }
546
547 // Extract the information of whether this variable is a primitive or not:
548 if( *itr == "0" ) {
549 m_primitive = false;
550 } else if( *itr == "1" ) {
551 m_primitive = true;
552 } else {
553 REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata::Variable" )
554 << "The received data can not be parsed successfully: "
555 << data;
556 return StatusCode::FAILURE;
557 }
558
559 return StatusCode::SUCCESS;
560 }
561
563
564 return ( ( name() == var.name() ) &&
565 ( type() == var.type() ) );
566 }
567
569
570 if( name() != var.name() ) {
571 return ( name() < var.name() );
572 } else {
573 return ( type() < var.type() );
574 }
575 }
576
577 const std::set< ObjectMetadata::Variable >& ObjectMetadata::variables() const {
578
579 return m_variables;
580 }
581
583 const ObjectMetadata& obj2 ) {
584
585 ObjectMetadata result( obj1 );
586 return result += obj2;
587 }
588
589} // namespace D3PD
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.
#define CHECK(...)
Evaluate an expression and check for errors.
double length(const pvec &v)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Internal class keeping track of a single variable.
bool operator<(const Variable &var) const
Operator needed to use such objects in STL containers.
const std::string & type() const
Type name of the variable.
bool m_primitive
Flag showing whether the variable is a primitive.
StatusCode read(const std::string &data)
Read data from a "serialized" string.
bool operator==(const Variable &var) const
Operator checking the equivalence of two variables.
std::string toString() const
Function "serializing" the variable information into a string.
std::string m_type
Full type name of the variable.
void setDoc(const std::string &doc)
Set the description of the variable.
void setPrimitive(bool primitive)
Set whether the variable is a primitive.
const std::string & doc() const
Description of the variable.
const std::string & name() const
Name of the variable without its prefix.
static const char *const STRING_SEPARATOR
Character separating parts of the variable's metadata.
std::string m_name
Name of the variable without its prefix.
void setName(const std::string &name)
Set the name of the variable.
bool primitive() const
Flag showing whether the variable is a primitive.
void setType(const std::string &type)
Set the type name of the variable.
std::string m_doc
Description of the variable.
D3PD variable metadata handling class.
static const size_t RANDOM_NAME_POSTFIX_LENGTH
Length of the random string appended to the object name.
void clear()
Function clearing the object.
const std::string & name() const
Get the name of the D3PDObject that this object describes.
static const unsigned int SERIALIZER_VERSION
"Version number" of the serialized information
ObjectMetadata & operator+=(const ObjectMetadata &obj)
Operator merging the contents of two objects.
std::set< Variable > m_variables
The list of variables created by a D3PDObject.
const std::set< Variable > & variables() const
Function for accessing all the variables of the D3PDObject.
bool m_container
The D3PDObject describes a container.
ObjectMetadata & operator=(const ObjectMetadata &parent)
Assignment operator.
virtual StatusCode addVariable(const std::string &name, const std::type_info &ti, void *&ptr, const std::string &docstring="", const void *defval=0)
This function can be used to save the metadata about a D3PD variable.
StatusCode read(const std::string &data)
Function "de-serializing" the stored information from a string.
std::string toString() const
Function "serializing" the stored information into a string.
std::string m_name
Name of the D3PDObject that this object describes.
void setPrefix(const std::string &prefix)
Set the prefix given to variables in this D3PDObject.
void setName(const std::string &name)
Set the name of the D3PDObject that this object describes.
ObjectMetadata & merge(const ObjectMetadata &obj)
Function merging the contents of two objects.
void setContainer(bool container)
Set whether the D3PDObject describes a container or not.
const std::string & prefix() const
Get the prefix given to variables in this D3PDObject.
std::string m_prefix
Prefix used by the D3PDObject.
static std::string objectName(const std::string &metaName)
Get the D3PDObject's name from the name of the metadata object.
ObjectMetadata()
Default constructor.
bool operator<(const ObjectMetadata &rhs) const
Operator needed to use such objects in ordered STL containers.
static const char *const STRING_SEPARATOR
Character separating parts of the object's metadata.
virtual StatusCode addDimensionedVariable(const std::string &name, const std::type_info &ti, void *&ptr, const std::string &dim, const std::string &docstring="", const void *defval=0)
The object doesn't support dimensioned variables at the moment, like most of the D3PDMaker code doesn...
bool operator==(const ObjectMetadata &rhs) const
Equality operator.
bool container() const
Get whether the D3PDObject describes a container or not.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
Block filler tool for noisy FEB information.
bool isPrimitive(const std::string &type)
This function is used in the code generator to determine from a type name if it's a primitive type or...
StatusCode DummyInitAlg::initialize ATLAS_NOT_THREAD_SAFE()
Standard Gaudi initialize method.
ObjectMetadata operator+(const ObjectMetadata &obj1, const ObjectMetadata &obj2)
Operator for creating the sum of two metadata objects.
Definition merge.py:1