The Gaudi Framework  v36r1 (3e2fb5a8)
VFSSvc.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 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 "VFSSvc.h"
12 
13 #include "GaudiKernel/IAlgTool.h"
14 #include "GaudiKernel/IToolSvc.h"
15 #include "GaudiKernel/MsgStream.h"
16 
18 
19 //------------------------------------------------------------------------------
20 StatusCode VFSSvc::initialize() {
22  if ( sc.isFailure() ) return sc;
23 
24  m_toolSvc = serviceLocator()->service( "ToolSvc" );
25  if ( !m_toolSvc ) {
26  error() << "Cannot locate ToolSvc" << endmsg;
27  return StatusCode::FAILURE;
28  }
29 
30  IAlgTool* tool;
31  for ( const auto& i : m_urlHandlersNames ) {
32  // retrieve the tool and the pointer to the interface
33  sc = m_toolSvc->retrieve( i, IAlgTool::interfaceID(), tool, nullptr, true );
34  if ( sc.isFailure() ) {
35  error() << "Cannot get tool " << i << endmsg;
36  return sc;
37  }
38  m_acquiredTools.push_back( tool ); // this is one tool that we will have to release
39  auto hndlr = SmartIF<IFileAccess>( tool );
40  if ( !hndlr ) {
41  error() << i << " does not implement IFileAccess" << endmsg;
42  return StatusCode::FAILURE;
43  }
44  // We do not need to increase the reference count for the IFileAccess interface
45  // because we hold the tool by its IAlgTool interface.
46  // loop over the list of supported protocols and add them to the map (for quick access)
47  for ( const auto& prot : hndlr->protocols() ) m_urlHandlers[prot].emplace_back( hndlr.get() );
48  }
49 
50  // Now let's check if we can handle the fallback protocol
51  if ( m_urlHandlers.find( m_fallBackProtocol ) == m_urlHandlers.end() ) {
52  error() << "No handler specified for fallback protocol prefix " << m_fallBackProtocol.value() << endmsg;
53  return StatusCode::FAILURE;
54  }
55 
56  // Note: the list of handled protocols will be filled only if requested
57 
58  return sc;
59 }
60 //------------------------------------------------------------------------------
62  m_urlHandlers.clear(); // clear the map
64 
65  if ( m_toolSvc ) {
66  // release the acquired tools (from the last acquired one)
67  while ( !m_acquiredTools.empty() ) {
68  m_toolSvc->releaseTool( m_acquiredTools.back() ).ignore();
70  }
71  m_toolSvc.reset(); // release the tool service
72  }
73  return Service::finalize();
74 }
75 //------------------------------------------------------------------------------
77  // get the url prefix endpos
78  auto pos = url.find( "://" );
79 
80  if ( std::string::npos == pos ) {
81  // no url prefix, try fallback protocol
82  return VFSSvc::open( m_fallBackProtocol + "://" + url );
83  }
84 
85  const std::string url_prefix( url, 0, pos );
86  const auto handlers = m_urlHandlers.find( url_prefix );
87  if ( handlers == m_urlHandlers.end() ) {
88  // if we do not have a handler for the URL prefix,
89  // use the fall back one
90  return VFSSvc::open( m_fallBackProtocol + url.substr( pos ) );
91  }
92 
93  std::unique_ptr<std::istream> out; // this might help RVO
94  // try the hendlers for the protocol one after the other until one succeds
95  for ( auto hndlr : handlers->second ) {
96  out = hndlr->open( url );
97  if ( out ) break;
98  }
99  return out;
100 }
101 //------------------------------------------------------------------------------
102 namespace {
105  constexpr struct select1st_t {
106  template <typename S, typename T>
107  const S& operator()( const std::pair<S, T>& x ) const {
108  return x.first;
109  }
110  } select1st{};
111 } // namespace
112 
114  if ( m_protocols.empty() ) {
115  // prepare the list of handled protocols
117  std::back_inserter( const_cast<VFSSvc*>( this )->m_protocols ), select1st );
118  }
119  return m_protocols;
120 }
Service::initialize
StatusCode initialize() override
Definition: Service.cpp:118
std::string
STL class.
IAlgTool
Definition: IAlgTool.h:33
GaudiUtils::Map::find
iterator find(const key_type &key)
Definition: Map.h:157
std::pair
VFSSvc::m_fallBackProtocol
Gaudi::Property< std::string > m_fallBackProtocol
Definition: VFSSvc.h:54
VFSSvc.h
std::vector< std::string >
SmartIF::reset
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:96
std::string::find
T find(T... args)
std::back_inserter
T back_inserter(T... args)
std::vector::back
T back(T... args)
VFSSvc::protocols
const std::vector< std::string > & protocols() const override
Definition: VFSSvc.cpp:113
GaudiUtils::Map::begin
iterator begin()
Definition: Map.h:139
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:222
std::vector::clear
T clear(T... args)
VFSSvc::finalize
StatusCode finalize() override
Finalize Service.
Definition: VFSSvc.cpp:61
IToolSvc.h
VFSSvc::m_acquiredTools
std::vector< IAlgTool * > m_acquiredTools
List of acquired tools (needed to release them).
Definition: VFSSvc.h:67
VFSSvc::m_protocols
std::vector< std::string > m_protocols
Protocols registered.
Definition: VFSSvc.h:58
VFSSvc
Definition: VFSSvc.h:36
GaudiUtils::Map::clear
void clear()
Definition: Map.h:195
bug_34121.tool
tool
Definition: bug_34121.py:17
StatusCode
Definition: StatusCode.h:65
VFSSvc::m_urlHandlers
GaudiUtils::HashMap< std::string, std::vector< IFileAccess * > > m_urlHandlers
Map of the tools handling the known protocols.
Definition: VFSSvc.h:61
IInterface::interfaceID
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:246
VFSSvc::m_toolSvc
SmartIF< IToolSvc > m_toolSvc
Handle to the tool service.
Definition: VFSSvc.h:64
IAlgTool.h
VFSSvc::open
std::unique_ptr< std::istream > open(const std::string &url) override
Definition: VFSSvc.cpp:76
SmartIF< IFileAccess >
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:203
std::vector::pop_back
T pop_back(T... args)
std::transform
T transform(T... args)
GaudiUtils::Map::end
iterator end()
Definition: Map.h:140
std::string::substr
T substr(T... args)
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:142
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
std::vector::empty
T empty(T... args)
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
std::unique_ptr
STL class.
MsgStream.h
PrepareBase.out
out
Definition: PrepareBase.py:20