fw4spl
Native.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwRuntime/dl/Native.hpp"
8 
9 #include "fwRuntime/Bundle.hpp"
10 #include "fwRuntime/Runtime.hpp"
11 
12 #include <boost/filesystem/operations.hpp>
13 #include <boost/filesystem/path.hpp>
14 
15 #include <limits.h>
16 
17 #include <string>
18 
19 namespace fwRuntime
20 {
21 
22 namespace dl
23 {
24 
25 //------------------------------------------------------------------------------
26 
27 Native::Native( const ::boost::filesystem::path& modulePath ) noexcept :
28  m_modulePath( modulePath ),
29  m_bundle( 0 )
30 {
31 }
32 
33 //------------------------------------------------------------------------------
34 
35 Native::~Native() noexcept
36 {
37 }
38 
39 //------------------------------------------------------------------------------
40 
41 const ::boost::filesystem::path Native::getBundleLocation() const
42 {
43 #ifdef ANDROID
44  return ::fwRuntime::Runtime::getDefault()->getWorkingPath() / "lib";
45 #else
46  return m_bundle->getLibraryLocation();
47 #endif
48 }
49 
50 //------------------------------------------------------------------------------
51 
52 const ::boost::filesystem::path Native::getFullPath( const bool _bMustBeFile ) const
53 {
54  // Pre-condition
55  SLM_ASSERT("bundle not initialized", m_bundle != 0 );
56 
57  ::boost::filesystem::path result;
58 
59  result = this->getBundleLocation() / this->getPath();
60 
61  // Test that the result path exists.
62  if(result.empty())
63  {
64  throw RuntimeException("Unable to find a native library for the bundle.");
65  }
66  if( !::boost::filesystem::exists(result) )
67  {
68  throw RuntimeException("'" + result.string() + "': invalid native module file name.");
69  }
70  if(_bMustBeFile && ::boost::filesystem::is_directory(result) )
71  {
72  throw RuntimeException("'" + result.string() + "': is a directory. Perhaps dynamic library is missing.");
73  }
74  return result;
75 }
76 
77 //------------------------------------------------------------------------------
78 
79 const ::boost::regex Native::getNativeName() const
80 {
81  const ::boost::filesystem::path fullModulePath( this->getBundleLocation() / m_modulePath );
82  ::boost::regex nativeName;
83 
84 #if defined(linux) || defined(__linux)
85  nativeName = ::boost::regex(
86  "lib" + fullModulePath.filename().string() + Bundle::s_VERSION_DELIMITER + m_bundle->getVersion().string() + "\\.so" +
87  "[0-9\\.]*" );
88 #elif defined(WIN32)
89  nativeName = ::boost::regex(
90  fullModulePath.filename().string() + Bundle::s_VERSION_DELIMITER + m_bundle->getVersion().string() +
91  "\\.dll");
92 #elif defined (__MACOSX__)
93  nativeName = ::boost::regex(
94  "lib" + fullModulePath.filename().string() + Bundle::s_VERSION_DELIMITER + m_bundle->getVersion().string() + "[0-9\\.]*" +
95  "\\.dylib" );
96 #endif
97 
98  return nativeName;
99 }
100 
101 //------------------------------------------------------------------------------
102 
103 const ::boost::filesystem::path Native::getPath() const
104 {
105  // Pre-condition
106  SLM_ASSERT("bundle not initialized", m_bundle != 0 );
107 
108  ::boost::filesystem::path result;
109 
110  const ::boost::filesystem::path fullModulePath( this->getBundleLocation() / m_modulePath );
111  const ::boost::regex nativeFileRegex( this->getNativeName() );
112 
113  // Walk through the module directory, seeking for a matching file.
114  ::boost::filesystem::directory_iterator curDirEntry(fullModulePath.parent_path());
115  ::boost::filesystem::directory_iterator endDirEntry;
116  for(; curDirEntry != endDirEntry; ++curDirEntry)
117  {
118  ::boost::filesystem::path curEntryPath( *curDirEntry );
119  if( ::boost::regex_match( curEntryPath.filename().string(), nativeFileRegex ) )
120  {
121  result = m_modulePath.parent_path() / curEntryPath.filename();
122  break;
123  }
124  }
125 
126  return result;
127 }
128 
129 //------------------------------------------------------------------------------
130 
131 void Native::setBundle( const Bundle* bundle ) noexcept
132 {
133  // Pre-condition
134  SLM_ASSERT("bundle already initialized", m_bundle == 0 );
135  m_bundle = bundle;
136  // Post-condition
137  SLM_ASSERT("bundle not correctly attached", m_bundle == bundle );
138 }
139 
140 //------------------------------------------------------------------------------
141 
142 void Native::operator=(const Native&) noexcept
143 {
144 }
145 
146 //------------------------------------------------------------------------------
147 
148 } // namespace dl
149 
150 } // namespace fwRuntime
virtual ~Native() noexcept
Destructor : does nothing.
Definition: Native.cpp:35
Defines the runtime exception class.
Native(const boost::filesystem::path &modulePath) noexcept
Constructor.
Definition: Native.cpp:27
const boost::filesystem::path getFullPath(const bool _bMustBeFile=false) const
Retrieves the file path of the library including the owning bundle&#39;s path.
Definition: Native.cpp:52
Defines the abstract class for native module implementors.
Definition: Native.hpp:31
FWRUNTIME_API const Version & getVersion() const
Retrieves the version of the bundle.
Definition: Bundle.cpp:296
The namespace fwRuntime contains classes to manage bundle, configuration element, extension point in ...
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
const boost::filesystem::path getPath() const
Retrieves the file path of the native library.
Definition: Native.cpp:103
const ::boost::regex getNativeName() const
Retrieves the pattern of the dynamic library file name given the host OS.
Definition: Native.cpp:79
Defines the bundle class.
Definition: Bundle.hpp:45
FWRUNTIME_API const std::string string() const
String converter.
FWRUNTIME_APIconst::boost::filesystem::path & getLibraryLocation() const
Retrieves the bundle location.
Definition: Bundle.cpp:275
void setBundle(const ::fwRuntime::Bundle *bundle) noexcept
Set the bundle the library is attached to.
Definition: Native.cpp:131