1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef _SALHELPER_DYNLOAD_HXX_
29 #define _SALHELPER_DYNLOAD_HXX_
30 
31 #include <sal/types.h>
32 #include <rtl/ustring.hxx>
33 #include <osl/module.h>
34 
35 namespace salhelper
36 {
37 
38 /** The ORealDynamicLoader is an implementation helper class for the template loader ODynamicLoader.
39  */
40 class ORealDynamicLoader
41 {
42 public:
43     /** initializes the loader, loads the library and call the initialization fucntion.
44 
45         @param ppSetToZeroInDestructor points to the loader instance which must be set to NULL
46                                        if the loader will be destroyed.
47         @param strModuleName specifies the library name.
48         @param strInitFunction specifies the name of the initialization function.
49      */
50 	static ORealDynamicLoader* SAL_CALL newInstance(
51 			ORealDynamicLoader ** ppSetToZeroInDestructor,
52 			const ::rtl::OUString& strModuleName,
53 			const ::rtl::OUString& strInitFunction );
54 
55     /// increase the reference count.
56 	sal_uInt32 SAL_CALL acquire();
57     /// decrease the reference count and delete the last instance.
58 	sal_uInt32 SAL_CALL release();
59 
60     /// returns a poiner to the initialized API function structure.
61 	void* SAL_CALL getApi() const;
62 
63 protected:
64     /** Constructor.
65 
66         @param ppSetToZeroInDestructor points to the loader instance which must be set to NULL
67                                        if the loader will be destroyed.
68         @param strModuleName specifies the library name.
69         @param strInitFunction specifies the name of the initialization function.
70         @param pApi points to a structure with the initialized API function pointers.
71         @param pModule points to the loaded library handle.
72      */
73 	ORealDynamicLoader( ORealDynamicLoader ** ppSetToZeroInDestructor,
74 						const ::rtl::OUString& strModuleName,
75 						const ::rtl::OUString& strInitFunction,
76 						void* pApi,
77 						oslModule pModule );
78 
79     /// Destructor, try to unload the library.
80 	virtual ~ORealDynamicLoader();
81 
82     /// points to  the structure with the initialzed API function pointers.
83 	void* 					m_pApi;
84     /// stores the reference count.
85 	sal_uInt32 				m_refCount;
86     /// stores the library handle.
87 	oslModule 				m_pModule;
88     /// stores the library name.
89     ::rtl::OUString 		m_strModuleName;
90     /// stores the name of the initialization function.
91 	::rtl::OUString 		m_strInitFunction;
92     /** stores a pointer to itself, which must be reset in the destructor to signal
93         that the loader is invalid.
94     */
95 	ORealDynamicLoader **  	ppSetToZeroInDestructor;
96 };
97 
98 
99 /** The ODynmaicLoader provides a special load on call mechanism for dynamic libraries
100     which support a C-API.
101 
102     The libraries must provide a struct with function pointers for all supported C functions.
103     The loader loads the specified library and call the specified initialization function
104     to initialize the function pointers with the real functions. Furthermore provides the
105     loader a reference counter for the library. When the last instance of the laoder will
106     be destroyed the loader will unload the library.
107 
108     @deprecated
109     Do not use.
110  */
111 template<class API>
112 class ODynamicLoader
113 {
114 public:
115     /// Default constructor
116 	ODynamicLoader() SAL_THROW(())
117 	{
118 		m_pLoader = 0;
119 	}
120 
121     /** Constructor, loads the library if necessary otherwise the refernece count will
122         be increased.
123 
124         @param strModuleName specifies the library name.
125         @param strInitFunction specifies the name of the initialization function.
126      */
127 	ODynamicLoader( const ::rtl::OUString& strModuleName,
128 		       		const ::rtl::OUString& strInitFunction ) SAL_THROW(())
129 	{
130 		if (!m_pStaticLoader)
131 		{
132 		    m_pStaticLoader = ORealDynamicLoader::newInstance(
133 		       &m_pStaticLoader,
134 		       strModuleName,
135 		       strInitFunction);
136 		}
137 		else
138 		{
139 		    m_pStaticLoader->acquire();
140 		}
141 
142 		m_pLoader = m_pStaticLoader;
143 	}
144 
145     /// Copy constructor
146 	ODynamicLoader(const ODynamicLoader<API>& toCopy) SAL_THROW(())
147 	{
148 		m_pLoader = toCopy.m_pLoader;
149 		if( m_pLoader )
150 		    m_pLoader->acquire();
151 	}
152 
153     /// Destructor, decrease the reference count and unload the library if it is tha last instance.
154 	~ODynamicLoader() SAL_THROW(())
155 	{
156 		if( m_pLoader )
157 		    m_pLoader->release();
158 	}
159 
160     /// Assign operator
161 	ODynamicLoader<API>& SAL_CALL operator = (const ODynamicLoader<API>& toAssign) SAL_THROW(())
162 	{
163 		if( m_pLoader != toAssign.m_pLoader )
164 		{
165 		    if( toAssign.m_pLoader )
166 			toAssign.m_pLoader->acquire();
167 		    if( m_pLoader )
168 			m_pLoader->release();
169 		    m_pLoader = toAssign.m_pLoader;
170 		}
171 
172 		return (*this);
173 	}
174 
175     /// returns a poiner to the initialized API function structure.
176 	API* SAL_CALL getApi() const SAL_THROW(())
177 	{
178 		return (API*)m_pLoader->getApi();
179 	}
180 
181     /// cast operator, which cast to a poiner with the initialized API function structure.
182 	API* SAL_CALL operator->() const SAL_THROW(())
183 	{
184 		return (API*)m_pLoader->getApi();
185 	}
186 
187     /// checks if the loader works on a loaded and initialized library.
188 	sal_Bool SAL_CALL isLoaded() const SAL_THROW(())
189 	{
190 		return (m_pLoader != NULL);
191 	}
192 
193 protected:
194     /// stores the real loader helper instance
195 	static ORealDynamicLoader* 	m_pStaticLoader;
196 	ORealDynamicLoader* 		m_pLoader;
197 };
198 
199 
200 template<class API>
201 ORealDynamicLoader* ODynamicLoader<API>::m_pStaticLoader = NULL;
202 
203 }
204 
205 #endif
206 
207