16#include <boost/algorithm/string.hpp>
20#include <unordered_map>
37 std::shared_ptr<TFile>
getFile(
const std::string& identifier )
override;
40 bool hasIdentifier(
const std::string& identifier )
const override;
45 this,
"Config", {},
"Map of keywords to file paths for file access" };
55 std::shared_ptr<TFile>
openFile(
const std::string& filePath,
const std::string& option,
int compress );
68 std::vector<std::shared_ptr<TFile>>
m_files;
80 std::map<std::string, std::string> parseFilePath(
const std::string& path ) {
81 std::vector<std::string> parts;
82 boost::split( parts, path, boost::is_any_of(
"?" ) );
83 std::map<std::string, std::string> result;
84 if ( parts.size() > 1 ) {
85 std::vector<std::string> params;
86 boost::split( params, parts[1], boost::is_any_of(
"&" ) );
87 for (
auto& param : params ) {
88 std::vector<std::string> kv;
89 boost::split( kv, param, boost::is_any_of(
"=" ) );
90 if ( kv.size() == 2 ) { result[boost::trim_copy( kv[0] )] = boost::trim_copy( kv[1] ); }
93 result[
"mode"] = ( result.find(
"mode" ) == result.end() ) ?
"CREATE" : result[
"mode"];
94 result[
"path"] = boost::trim_copy( parts[0] );
107 StatusCode checkConfig(
const std::map<std::string, std::string>& configMap,
const FileSvc& svc ) {
108 std::map<std::string, std::map<std::string, std::string>> fileParams;
109 for (
const auto& [identifier, path] : configMap ) {
110 auto params = parseFilePath( path );
112 auto& existingParams = fileParams[params[
"path"]];
113 if ( !existingParams.empty() ) {
114 if ( existingParams != params ) {
115 svc.
error() <<
"Conflicting configurations for file path: " << params[
"path"] <<
endmsg;
119 existingParams = std::move( params );
132 std::optional<size_t> findFileIndex(
const std::vector<std::shared_ptr<TFile>>& files,
const std::string& filePath ) {
133 auto it = std::find_if( files.begin(), files.end(),
134 [&filePath](
const auto& file ) { return file && file->GetName() == filePath; } );
135 if ( it != files.end() ) {
return std::distance( files.begin(), it ); }
146 for (
const auto& [identifier, path] :
m_config ) {
147 auto params = parseFilePath( path );
150 if (
auto fileIndex = findFileIndex(
m_files, params[
"path"] ) ) {
152 m_identifiers[boost::to_lower_copy( identifier )] = *fileIndex;
155 int compress = ( params.find(
"compress" ) != params.end() )
156 ? std::stoi( params[
"compress"] )
157 : ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault;
158 if (
auto file =
openFile( path, params[
"mode"], compress ) ) {
159 m_files.push_back( std::move( file ) );
162 error() <<
"Failed to open file: " << params[
"path"] <<
endmsg;
175 auto it =
m_identifiers.find( boost::to_lower_copy( identifier ) );
177 error() <<
"No file associated with identifier: " << identifier <<
endmsg;
185std::shared_ptr<TFile>
FileSvc::openFile(
const std::string& filePath,
const std::string& option,
int compress ) {
186 auto file = std::make_shared<TFile>( filePath.c_str(), option.c_str(),
"", compress );
187 if ( !file || file->IsZombie() ) {
return nullptr; }
192 for (
const auto& file :
m_files ) {
193 if ( file ) { file->Close(); }
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
#define DECLARE_COMPONENT(type)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Gaudi::Property< std::map< std::string, std::string > > m_config
StatusCode closeFiles()
Close all files.
std::vector< std::shared_ptr< TFile > > m_files
StatusCode initialize() override
bool hasIdentifier(const std::string &identifier) const override
Check if a given identifier is known to the service.
StatusCode finalize() override
std::unordered_map< std::string, size_t > m_identifiers
FileSvc(const std::string &name, ISvcLocator *svc)
std::shared_ptr< TFile > getFile(const std::string &identifier) override
Get a TFile pointer based on an identifier.
std::shared_ptr< TFile > openFile(const std::string &filePath, const std::string &option, int compress)
Open a file based on a specified path and opening mode.
Implementation of property with value of concrete type.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
const std::string & name() const override
Retrieve name of the service.
StatusCode initialize() override
This class is used for returning status codes from appropriate routines.
StatusCode andThen(F &&f, ARGS &&... args) const
Chain code blocks making the execution conditional a success result.
constexpr static const auto SUCCESS
constexpr static const auto FAILURE
Base class used to extend a class implementing other interfaces.