TuttleOFX
1
|
00001 /* 00002 * Software License : 00003 * 00004 * Copyright (c) 2007-2009, The Open Effects Association Ltd. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * Neither the name The Open Effects Association Ltd, nor the names of its 00015 * contributors may be used to endorse or promote products derived from this 00016 * software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00019 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00020 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00021 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 00022 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00023 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00024 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00025 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00026 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00027 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 #include "OfxhBinary.hpp" 00031 #include <tuttle/host/exceptions.hpp> 00032 00033 namespace tuttle { 00034 namespace host { 00035 namespace ofx { 00036 00037 OfxhBinary::OfxhBinary() 00038 : _binaryPath() 00039 , _invalid( false ) 00040 , _dlHandle( NULL ) 00041 , _exists( false ) 00042 , _time( 0 ) 00043 , _size( 0 ) 00044 , _users( 0 ) 00045 {} 00046 00047 OfxhBinary::OfxhBinary( const std::string& binaryPath ) 00048 : _binaryPath( binaryPath ) 00049 , _invalid( false ) 00050 , _dlHandle( NULL ) 00051 , _exists( false ) 00052 , _time( 0 ) 00053 , _size( 0 ) 00054 , _users( 0 ) 00055 { 00056 init( binaryPath ); 00057 } 00058 00059 void OfxhBinary::init( const std::string& binaryPath ) 00060 { 00061 struct stat sb; 00062 00063 _binaryPath = binaryPath; 00064 00065 if( stat( binaryPath.c_str(), &sb ) != 0 ) 00066 { 00067 _invalid = true; 00068 } 00069 else 00070 { 00071 _time = sb.st_mtime; 00072 _size = sb.st_size; 00073 } 00074 } 00075 00076 // actually open the binary. 00077 void OfxhBinary::load() 00078 { 00079 if( _invalid ) 00080 return; 00081 00082 #if defined ( UNIX ) 00083 _dlHandle = dlopen( _binaryPath.c_str(), RTLD_LAZY ); 00084 #else 00085 //std::cout << "LoadLibrary" << _binaryPath << std::endl; 00086 _dlHandle = LoadLibrary( _binaryPath.c_str() ); 00087 //std::cout << "_dlHandle: " << _dlHandle << std::endl; 00088 #endif 00089 if( _dlHandle == 0 ) 00090 { 00091 _invalid = true; 00092 #if defined ( UNIX ) 00093 BOOST_THROW_EXCEPTION( exception::File() 00094 << exception::user() + "Couldn't open library because " + quotes(dlerror()) 00095 << exception::filename( _binaryPath ) ); 00096 #else 00097 LPVOID lpMsgBuf = NULL; 00098 DWORD err = GetLastError(); 00099 00100 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | 00101 FORMAT_MESSAGE_FROM_SYSTEM | 00102 FORMAT_MESSAGE_IGNORE_INSERTS, 00103 NULL, 00104 err, 00105 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), 00106 (LPTSTR) &lpMsgBuf, 00107 0, NULL ); 00108 exception::user userMsg; 00109 userMsg + "Couldn't open library because " + quotes((char*)lpMsgBuf) + " was returned"; 00110 if( lpMsgBuf != NULL ) 00111 { 00112 LocalFree( lpMsgBuf ); 00113 } 00114 BOOST_THROW_EXCEPTION( exception::File() 00115 << userMsg 00116 << exception::filename( _binaryPath ) ); 00117 #endif 00118 } 00119 } 00120 00121 /// close the binary 00122 void OfxhBinary::unload() 00123 { 00124 if( _dlHandle != 0 ) 00125 { 00126 #if defined ( UNIX ) 00127 dlclose( _dlHandle ); 00128 #elif defined ( WINDOWS ) 00129 FreeLibrary( _dlHandle ); 00130 #endif 00131 _dlHandle = 0; 00132 } 00133 } 00134 00135 /// look up a symbol in the binary file and return it as a pointer. 00136 /// returns null pointer if not found. 00137 void* OfxhBinary::findSymbol( const std::string& symbol ) 00138 { 00139 if( _invalid || _dlHandle == 0 ) 00140 { 00141 BOOST_THROW_EXCEPTION( exception::File() 00142 << exception::user() + "Error while loading plugin." 00143 << exception::dev() + "Can't search for symbol " + quotes( symbol ) + " (invalid:" + _invalid + ", dlHandle:" + _dlHandle + ")." 00144 << exception::filename( _binaryPath ) ); 00145 } 00146 #if defined( UNIX ) 00147 return dlsym( _dlHandle, symbol.c_str() ); 00148 #elif defined ( WINDOWS ) 00149 return (void*)GetProcAddress( _dlHandle, symbol.c_str() ); 00150 #endif 00151 } 00152 00153 void OfxhBinary::ref() 00154 { 00155 if( _users == 0 ) 00156 { 00157 load(); 00158 } 00159 ++_users; 00160 } 00161 00162 void OfxhBinary::unref() 00163 { 00164 --_users; 00165 if( _users == 0 ) 00166 { 00167 unload(); 00168 } 00169 if( _users < 0 ) 00170 { 00171 _users = 0; 00172 } 00173 } 00174 00175 } 00176 } 00177 }