1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _SALHELPER_DYNLOAD_HXX_
25 #define _SALHELPER_DYNLOAD_HXX_
26 
27 #include <sal/types.h>
28 #include <rtl/ustring.hxx>
29 #include <osl/module.h>
30 
31 namespace salhelper
32 {
33 
34 /** The ORealDynamicLoader is an implementation helper class for the template loader ODynamicLoader.
35  */
36 class ORealDynamicLoader
37 {
38 public:
39     /** initializes the loader, loads the library and call the initialization fucntion.
40 
41         @param ppSetToZeroInDestructor points to the loader instance which must be set to NULL
42                                        if the loader will be destroyed.
43         @param strModuleName specifies the library name.
44         @param strInitFunction specifies the name of the initialization function.
45      */
46 	static ORealDynamicLoader* SAL_CALL newInstance(
47 			ORealDynamicLoader ** ppSetToZeroInDestructor,
48 			const ::rtl::OUString& strModuleName,
49 			const ::rtl::OUString& strInitFunction );
50 
51     /// increase the reference count.
52 	sal_uInt32 SAL_CALL acquire();
53     /// decrease the reference count and delete the last instance.
54 	sal_uInt32 SAL_CALL release();
55 
56     /// returns a poiner to the initialized API function structure.
57 	void* SAL_CALL getApi() const;
58 
59 protected:
60     /** Constructor.
61 
62         @param ppSetToZeroInDestructor points to the loader instance which must be set to NULL
63                                        if the loader will be destroyed.
64         @param strModuleName specifies the library name.
65         @param strInitFunction specifies the name of the initialization function.
66         @param pApi points to a structure with the initialized API function pointers.
67         @param pModule points to the loaded library handle.
68      */
69 	ORealDynamicLoader( ORealDynamicLoader ** ppSetToZeroInDestructor,
70 						const ::rtl::OUString& strModuleName,
71 						const ::rtl::OUString& strInitFunction,
72 						void* pApi,
73 						oslModule pModule );
74 
75     /// Destructor, try to unload the library.
76 	virtual ~ORealDynamicLoader();
77 
78     /// points to  the structure with the initialzed API function pointers.
79 	void* 					m_pApi;
80     /// stores the reference count.
81 	sal_uInt32 				m_refCount;
82     /// stores the library handle.
83 	oslModule 				m_pModule;
84     /// stores the library name.
85     ::rtl::OUString 		m_strModuleName;
86     /// stores the name of the initialization function.
87 	::rtl::OUString 		m_strInitFunction;
88     /** stores a pointer to itself, which must be reset in the destructor to signal
89         that the loader is invalid.
90     */
91 	ORealDynamicLoader **  	ppSetToZeroInDestructor;
92 };
93 
94 
95 /** The ODynmaicLoader provides a special load on call mechanism for dynamic libraries
96     which support a C-API.
97 
98     The libraries must provide a struct with function pointers for all supported C functions.
99     The loader loads the specified library and call the specified initialization function
100     to initialize the function pointers with the real functions. Furthermore provides the
101     loader a reference counter for the library. When the last instance of the laoder will
102     be destroyed the loader will unload the library.
103 
104     @deprecated
105     Do not use.
106  */
107 template<class API>
108 class ODynamicLoader
109 {
110 public:
111     /// Default constructor
112 	ODynamicLoader() SAL_THROW(())
113 	{
114 		m_pLoader = 0;
115 	}
116 
117     /** Constructor, loads the library if necessary otherwise the refernece count will
118         be increased.
119 
120         @param strModuleName specifies the library name.
121         @param strInitFunction specifies the name of the initialization function.
122      */
ODynamicLoader(const::rtl::OUString & strModuleName,const::rtl::OUString & strInitFunction)123 	ODynamicLoader( const ::rtl::OUString& strModuleName,
124 		       		const ::rtl::OUString& strInitFunction ) SAL_THROW(())
125 	{
126 		if (!m_pStaticLoader)
127 		{
128 		    m_pStaticLoader = ORealDynamicLoader::newInstance(
129 		       &m_pStaticLoader,
130 		       strModuleName,
131 		       strInitFunction);
132 		}
133 		else
134 		{
135 		    m_pStaticLoader->acquire();
136 		}
137 
138 		m_pLoader = m_pStaticLoader;
139 	}
140 
141     /// Copy constructor
142 	ODynamicLoader(const ODynamicLoader<API>& toCopy) SAL_THROW(())
143 	{
144 		m_pLoader = toCopy.m_pLoader;
145 		if( m_pLoader )
146 		    m_pLoader->acquire();
147 	}
148 
149     /// Destructor, decrease the reference count and unload the library if it is tha last instance.
150 	~ODynamicLoader() SAL_THROW(())
151 	{
152 		if( m_pLoader )
153 		    m_pLoader->release();
154 	}
155 
156     /// Assign operator
operator =(const ODynamicLoader<API> & toAssign)157 	ODynamicLoader<API>& SAL_CALL operator = (const ODynamicLoader<API>& toAssign) SAL_THROW(())
158 	{
159 		if( m_pLoader != toAssign.m_pLoader )
160 		{
161 		    if( toAssign.m_pLoader )
162 			toAssign.m_pLoader->acquire();
163 		    if( m_pLoader )
164 			m_pLoader->release();
165 		    m_pLoader = toAssign.m_pLoader;
166 		}
167 
168 		return (*this);
169 	}
170 
171     /// returns a poiner to the initialized API function structure.
getApi() const172 	API* SAL_CALL getApi() const SAL_THROW(())
173 	{
174 		return (API*)m_pLoader->getApi();
175 	}
176 
177     /// cast operator, which cast to a poiner with the initialized API function structure.
operator ->() const178 	API* SAL_CALL operator->() const SAL_THROW(())
179 	{
180 		return (API*)m_pLoader->getApi();
181 	}
182 
183     /// checks if the loader works on a loaded and initialized library.
isLoaded() const184 	sal_Bool SAL_CALL isLoaded() const SAL_THROW(())
185 	{
186 		return (m_pLoader != NULL);
187 	}
188 
189 protected:
190     /// stores the real loader helper instance
191 	static ORealDynamicLoader* 	m_pStaticLoader;
192 	ORealDynamicLoader* 		m_pLoader;
193 };
194 
195 
196 template<class API>
197 ORealDynamicLoader* ODynamicLoader<API>::m_pStaticLoader = NULL;
198 
199 }
200 
201 #endif
202 
203