The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
VFSSvc.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#include <GaudiKernel/HashMap.h>
16#include <GaudiKernel/Service.h>
17#include <list>
18
29
30class VFSSvc : public extends<Service, IFileAccess> {
31public:
33 using extends::extends;
35 StatusCode initialize() override;
37 StatusCode finalize() override;
38
40 std::unique_ptr<std::istream> open( std::string const& url ) override;
41
43 const std::vector<std::string>& protocols() const override;
44
45private:
47 this, "FileAccessTools", { { "FileReadTool" } }, "List of tools implementing the IFileAccess interface." };
48 Gaudi::Property<std::string> m_fallBackProtocol{ this, "FallBackProtocol", "file",
49 "URL prefix to use if the prefix is not present." };
50
52 std::vector<std::string> m_protocols;
53
56
59
61 std::vector<IAlgTool*> m_acquiredTools;
62};
63
65
66//------------------------------------------------------------------------------
69 if ( sc.isFailure() ) return sc;
70
71 m_toolSvc = serviceLocator()->service( "ToolSvc" );
72 if ( !m_toolSvc ) {
73 error() << "Cannot locate ToolSvc" << endmsg;
75 }
76
77 IAlgTool* tool;
78 for ( const auto& i : m_urlHandlersNames ) {
79 // retrieve the tool and the pointer to the interface
80 sc = m_toolSvc->retrieve( i, IAlgTool::interfaceID(), tool, nullptr, true );
81 if ( sc.isFailure() ) {
82 error() << "Cannot get tool " << i << endmsg;
83 return sc;
84 }
85 m_acquiredTools.push_back( tool ); // this is one tool that we will have to release
86 auto hndlr = SmartIF<IFileAccess>( tool );
87 if ( !hndlr ) {
88 error() << i << " does not implement IFileAccess" << endmsg;
90 }
91 // We do not need to increase the reference count for the IFileAccess interface
92 // because we hold the tool by its IAlgTool interface.
93 // loop over the list of supported protocols and add them to the map (for quick access)
94 for ( const auto& prot : hndlr->protocols() ) m_urlHandlers[prot].emplace_back( hndlr.get() );
95 }
96
97 // Now let's check if we can handle the fallback protocol
98 if ( m_urlHandlers.find( m_fallBackProtocol ) == m_urlHandlers.end() ) {
99 error() << "No handler specified for fallback protocol prefix " << m_fallBackProtocol.value() << endmsg;
100 return StatusCode::FAILURE;
101 }
102
103 // Note: the list of handled protocols will be filled only if requested
104
105 return sc;
106}
107//------------------------------------------------------------------------------
109 m_urlHandlers.clear(); // clear the map
110 m_protocols.clear();
111
112 if ( m_toolSvc ) {
113 // release the acquired tools (from the last acquired one)
114 while ( !m_acquiredTools.empty() ) {
115 m_toolSvc->releaseTool( m_acquiredTools.back() ).ignore();
116 m_acquiredTools.pop_back();
117 }
118 m_toolSvc.reset(); // release the tool service
119 }
120 return Service::finalize();
121}
122//------------------------------------------------------------------------------
123std::unique_ptr<std::istream> VFSSvc::open( std::string const& url ) {
124 // get the url prefix endpos
125 auto pos = url.find( "://" );
126
127 if ( url.npos == pos ) {
128 // no url prefix, try fallback protocol
129 return VFSSvc::open( std::string{ m_fallBackProtocol }.append( "://" ).append( url ) );
130 }
131
132 const std::string url_prefix( url, 0, pos );
133 const auto handlers = m_urlHandlers.find( url_prefix );
134 if ( handlers == m_urlHandlers.end() ) {
135 // if we do not have a handler for the URL prefix,
136 // use the fall back one
137 return VFSSvc::open( std::string{ m_fallBackProtocol }.append( url.substr( pos ) ) );
138 }
139
140 std::unique_ptr<std::istream> out; // this might help RVO
141 // try the hendlers for the protocol one after the other until one succeds
142 for ( auto hndlr : handlers->second ) {
143 out = hndlr->open( url );
144 if ( out ) break;
145 }
146 return out;
147}
148
149//------------------------------------------------------------------------------
150const std::vector<std::string>& VFSSvc::protocols() const {
151 if ( m_protocols.empty() ) {
152 // prepare the list of handled protocols
153 std::transform( m_urlHandlers.begin(), m_urlHandlers.end(),
154 std::back_inserter( const_cast<VFSSvc*>( this )->m_protocols ),
155 []( const auto& pair ) { return pair.first; } );
156 }
157 return m_protocols;
158}
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
#define DECLARE_COMPONENT(type)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Implementation of property with value of concrete type.
Definition PropertyFwd.h:27
Common class providing an architecture-independent hash map.
Definition HashMap.h:80
The interface implemented by the AlgTool base class.
Definition IAlgTool.h:29
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition IInterface.h:234
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition Service.cpp:336
StatusCode finalize() override
Definition Service.cpp:223
StatusCode initialize() override
Definition Service.cpp:118
Small smart pointer class with automatic reference counting for IInterface.
Definition SmartIF.h:28
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isFailure() const
Definition StatusCode.h:129
constexpr static const auto FAILURE
Definition StatusCode.h:100
Simple service that allows to read files independently from the storage.
Definition VFSSvc.cpp:30
std::vector< IAlgTool * > m_acquiredTools
List of acquired tools (needed to release them).
Definition VFSSvc.cpp:61
Gaudi::Property< std::string > m_fallBackProtocol
Definition VFSSvc.cpp:48
Gaudi::Property< std::vector< std::string > > m_urlHandlersNames
Definition VFSSvc.cpp:46
StatusCode initialize() override
Initialize Service.
Definition VFSSvc.cpp:67
const std::vector< std::string > & protocols() const override
Definition VFSSvc.cpp:150
StatusCode finalize() override
Finalize Service.
Definition VFSSvc.cpp:108
std::unique_ptr< std::istream > open(std::string const &url) override
Definition VFSSvc.cpp:123
std::vector< std::string > m_protocols
Protocols registered.
Definition VFSSvc.cpp:52
SmartIF< IToolSvc > m_toolSvc
Handle to the tool service.
Definition VFSSvc.cpp:58
GaudiUtils::HashMap< std::string, std::vector< IFileAccess * > > m_urlHandlers
Map of the tools handling the known protocols.
Definition VFSSvc.cpp:55
Base class used to extend a class implementing other interfaces.
Definition extends.h:19