TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/host/ofx/OfxhBinary.cpp
Go to the documentation of this file.
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 }