42 #include "uhal/log/log.hpp" 44 #include <boost/regex.hpp> 45 #include <boost/spirit/include/qi.hpp> 48 #if BOOST_VERSION >= 106000 50 using boost::placeholders::_1;
51 using boost::placeholders::_2;
52 using boost::placeholders::_3;
61 connection_file ( aConnectionFile )
85 if (
id != aConnectionDescriptor.
id )
90 if (
uri != aConnectionDescriptor.
uri )
118 boost::lock_guard<boost::mutex> lLock (
mMutex );
119 std::vector< std::pair<std::string, std::string> > lConnectionFiles;
122 for ( std::vector< std::pair<std::string, std::string> >::iterator lIt = lConnectionFiles.begin() ; lIt != lConnectionFiles.end() ; ++lIt )
141 boost::lock_guard<boost::mutex> lLock (
mMutex );
145 exception::ConnectionUIDDoesNotExist lExc;
146 log ( lExc ,
"Connection map contains no entries" );
154 exception::ConnectionUIDDoesNotExist lExc;
155 log ( lExc ,
"Device ID , " ,
Quote ( aId ) ,
", does not exist in connection map" );
161 log (
Info() ,
"ConnectionManager created node tree: " , *lNode );
170 boost::lock_guard<boost::mutex> lLock (
mMutex );
172 log (
Info() ,
"ConnectionManager created node tree: " , *lNode );
181 std::vector<std::string> lDevices;
186 lDevices.push_back ( lIt->first );
195 std::vector<std::string> lDevices;
200 boost::cmatch lMatch;
202 if ( boost::regex_match ( lIt->first.c_str() , lMatch , boost::regex ( aRegex ) ) )
204 lDevices.push_back ( lIt->first );
215 boost::lock_guard<boost::mutex> lLock (
mMutex );
216 log(
Info(),
"ConnectionManager is clearing the address filename -> Node tree cache");
224 std::pair< std::set< std::string >::iterator ,
bool > lInsert =
mPreviouslyOpenedFiles.insert ( aProtocol+ ( aPath.string() ) );
226 if ( ! lInsert.second )
228 log (
Info() ,
"File " ,
Quote ( aProtocol+ ( aPath.string() ) ) ,
" has already been parsed. I am not reparsing and will continue with next document for now but be aware!" );
232 pugi::xml_document lXmlDocument;
233 pugi::xml_parse_result lLoadResult = lXmlDocument.load_buffer_inplace ( & ( aFile[0] ) , aFile.size() );
242 pugi::xpath_node_set lConnections = lXmlDocument.select_nodes (
"/connections/connection" );
244 for ( pugi::xpath_node_set::const_iterator lConnectionIt = lConnections.begin(); lConnectionIt != lConnections.end(); ++lConnectionIt )
251 std::pair< std::map< std::string, ConnectionDescriptor >::iterator ,
bool > lInsert =
mConnectionDescriptors.insert ( std::make_pair ( lDescriptor.id , lDescriptor ) );
253 if ( !lInsert.second )
255 if ( lInsert.first->second == lDescriptor )
257 log (
Info() ,
"Duplicate connection entry found:" 258 "\n > id = " , lDescriptor.id ,
259 "\n > uri = " , lDescriptor.uri ,
260 "\n > address_table = " , lDescriptor.address_table ,
261 "\n Continuing for now but be aware!" );
265 exception::DuplicatedUID lExc;
266 log ( lExc ,
"Duplicate connection ID " ,
Quote ( lDescriptor.id ) ,
" found in connections file " ,
267 Quote ( aProtocol+ ( aPath.string() ) ) ,
" but parameters do not match! Bailing!" );
274 log (
Error() ,
"Construction of Connection Descriptor failed. Continuing with next Connection Descriptor for now but be aware!" );
void ParseSemicolonDelimitedUriList(const std::string &aSemicolonDelimitedUriList, std::vector< std::pair< std::string, std::string > > &aUriList)
Parse a semicolon delimited list of URIs into a vector of protocol/address pairs. ...
std::map< std::string, ConnectionDescriptor > mConnectionDescriptors
A map of connection identifiers to stucts containing details of the parsed XML node.
A class which bundles a node tree and an IPbus client interface together providing everything you nee...
static ClientFactory & getInstance()
Static method to retrieve the single instance of the class.
virtual ~ConnectionManager()
Destructor.
ConnectionManager(const std::string &aFilenameExpr)
Default constructor Given a semi-colon delimeted list of glob expressions, parse all the files matchi...
std::string address_table
The address table for building the node tree.
static boost::mutex mMutex
A mutex lock to protect access to the factory methods in multithreaded environments.
void clearAddressFileCache()
Clears address filename -> Node tree cache. NOT thread safe; for tread-safety, use ConnectionManager ...
HwInterface getDevice(const std::string &aId)
Retrieves protocol, host, and port from the connection file to create an IPbus Client Retrieves the a...
template bool GetXMLattribute< true >(const pugi::xml_node &aNode, const char *aAttrName, std::string &aTarget)
std::string uri
The full uri for making the connection.
void PugiXMLParseResultPrettifier(const pugi::xml_parse_result &aLoadResult, const boost::filesystem::path &aPath, const std::vector< uint8_t > &aFile)
Helper function to make debugging failures when parsing XML files easier.
_Quote< T > Quote(const T &aT)
std::set< std::string > mPreviouslyOpenedFiles
A set of previously opened filenames, so that the same file is not parsed multiple times...
ConnectionDescriptor(const pugi::xml_node &aNode, const boost::filesystem::path &aConnectionFile, bool &aSuccess)
Constructor.
static NodeTreeBuilder & getInstance()
Static method to retrieve the single instance of the class.
A struct to hold the fields of each entry in the XML connections file.
std::string id
An identifier for an individual.
std::vector< std::string > getDevices() const
Return all device IDs known to this connection manager.
bool operator==(const ConnectionDescriptor &aConnectionDescriptor) const
Comparison operation.
void OpenFile(const std::string &aProtocol, const std::string &aFilenameExpr, const boost::filesystem::path &aParentPath, boost::_bi::bind_t< R, F, L > aBinder)
Given a protocol and either a URL or a linux shell expression, open the file and call the callback fu...
static void clearAddressFileCache()
Clears cache of Node tree structure for previously-opened address files (thread safe) ...
void CallBack(const std::string &aProtocol, const boost::filesystem::path &aPath, std::vector< uint8_t > &aFile)
Method called once the file specified in the constructor has been opened.