This file is indexed.

/usr/include/pion/PluginManager.hpp is in libpion-common-dev 4.0.7+dfsg-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
// -----------------------------------------------------------------------
// pion-common: a collection of common libraries used by the Pion Platform
// -----------------------------------------------------------------------
// Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
//
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
//

#ifndef __PION_PLUGINMANAGER_HEADER__
#define __PION_PLUGINMANAGER_HEADER__

#include <map>
#include <string>
#include <boost/cstdint.hpp>
#include <boost/function.hpp>
#include <boost/function/function1.hpp>
#include <boost/thread/mutex.hpp>
#include <pion/PionConfig.hpp>
#include <pion/PionException.hpp>
#include <pion/PionPlugin.hpp>


namespace pion {	// begin namespace pion

///
/// PluginManager: used to manage a collection of plug-in objects
///
template <typename PLUGIN_TYPE>
class PluginManager
{
public:

	/// exception thrown if a plug-in cannot be found
	class PluginNotFoundException : public PionException {
	public:
		PluginNotFoundException(const std::string& plugin_id)
			: PionException("No plug-ins found for identifier: ", plugin_id) {}
	};

	/// exception thrown if we try to add or load a duplicate plug-in
	class DuplicatePluginException : public PionException {
	public:
		DuplicatePluginException(const std::string& plugin_id)
			: PionException("A plug-in already exists for identifier: ", plugin_id) {}
	};
	
	/// data type for a function that may be called by the run() method
	typedef boost::function1<void, PLUGIN_TYPE*>	PluginRunFunction;

	/// data type for a function that may be called by the getStat() method
	typedef boost::function1<boost::uint64_t, const PLUGIN_TYPE*>	PluginStatFunction;

	
	/// default constructor
	PluginManager(void) {}

	/// default destructor
	virtual ~PluginManager() {}

	/// clears all the plug-in objects being managed
	inline void clear(void) {
		boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
		m_plugin_map.clear();
	}
	
	/// returns true if there are no plug-in objects being managed
	inline bool empty(void) const { 
		boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
		return m_plugin_map.empty();
	}
	
	/**
	 * adds a new plug-in object
	 *
	 * @param plugin_id unique identifier associated with the plug-in
	 * @param plugin_object_ptr pointer to the plug-in object to add
	 */
	inline void add(const std::string& plugin_id, PLUGIN_TYPE *plugin_object_ptr);
	
	/**
	 * removes a plug-in object
	 *
	 * @param plugin_id unique identifier associated with the plug-in
	 */
	inline void remove(const std::string& plugin_id);
	
	/**
	 * replaces an existing plug-in object with a new one
	 *
	 * @param plugin_id unique identifier associated with the plug-in
	 * @param plugin_ptr pointer to the new plug-in object which will replace the old one
	 */
	inline void replace(const std::string& plugin_id, PLUGIN_TYPE *plugin_ptr);
	
	/**
	 * clones an existing plug-in object (creates a new one of the same type)
	 *
	 * @param plugin_id unique identifier associated with the plug-in
	 * @return PLUGIN_TYPE* pointer to the new plug-in object
	 */
	inline PLUGIN_TYPE *clone(const std::string& plugin_id);

	/**
	 * loads a new plug-in object
	 *
	 * @param plugin_id unique identifier associated with the plug-in
	 * @param plugin_type the name or type of the plug-in to load (searches
	 *                    plug-in directories and appends extensions)
	 * @return PLUGIN_TYPE* pointer to the new plug-in object
	 */
	inline PLUGIN_TYPE *load(const std::string& plugin_id, const std::string& plugin_type);
	
	/**
	 * gets the plug-in object associated with a particular plugin_id (exact match)
	 *
	 * @param plugin_id unique identifier associated with the plug-in
	 * @return PLUGIN_TYPE* pointer to the matching plug-in object or NULL if not found
	 */
	inline PLUGIN_TYPE *get(const std::string& plugin_id);
	
	/**
	 * gets the plug-in object associated with a particular plugin_id (exact match)
	 *
	 * @param plugin_id unique identifier associated with the plug-in
	 * @return PLUGIN_TYPE* pointer to the matching plug-in object or NULL if not found
	 */
	inline const PLUGIN_TYPE *get(const std::string& plugin_id) const;
	
	/**
	 * gets a smart pointer to the plugin shared library for a particular plugin_id (exact match)
	 *
	 * @param plugin_id unique identifier associated with the plug-in
	 * @return PionPluginPtr<PLUGIN_TYPE> pointer to the plugin shared library if found
	 */
	inline PionPluginPtr<PLUGIN_TYPE> getLibPtr(const std::string& plugin_id) const;
	
	/**
	 * finds the plug-in object associated with a particular resource (fuzzy match)
	 *
	 * @param resource resource identifier (uri-stem) to search for
	 * @return PLUGIN_TYPE* pointer to the matching plug-in object or NULL if not found
	 */
	inline PLUGIN_TYPE *find(const std::string& resource);
	
	/**
	 * runs a method for every plug-in being managed
	 *
	 * @param run_func the function to execute for each plug-in object
	 */
	inline void run(PluginRunFunction run_func);
	
	/**
	 * runs a method for a particular plug-in
	 *
	 * @param plugin_id unique identifier associated with the plug-in
	 * @param run_func the function to execute
	 */
	inline void run(const std::string& plugin_id, PluginRunFunction run_func);
	
	/**
	 * returns a total statistic value summed for every plug-in being managed
	 *
	 * @param stat_func the statistic function to execute for each plug-in object
	 */
	inline boost::uint64_t getStatistic(PluginStatFunction stat_func) const;
	
	/**
	 * returns a statistic value for a particular plug-in
	 *
	 * @param plugin_id unique identifier associated with the plug-in
	 * @param stat_func the statistic function to execute
	 */
	inline boost::uint64_t getStatistic(const std::string& plugin_id,
										PluginStatFunction stat_func) const;
		
	
protected:
	
	/// data type that maps identifiers to plug-in objects
	class PluginMap
		: public std::map<std::string, std::pair<PLUGIN_TYPE *, PionPluginPtr<PLUGIN_TYPE> > >
	{
	public:
		inline void clear(void);
		virtual ~PluginMap() { PluginMap::clear(); }
		PluginMap(void) {}
	};
	
	/// collection of plug-in objects being managed
	PluginMap						m_plugin_map;

	/// mutex to make class thread-safe
	mutable boost::mutex			m_plugin_mutex;
};

	
// PluginManager member functions

template <typename PLUGIN_TYPE>
inline void PluginManager<PLUGIN_TYPE>::add(const std::string& plugin_id,
											PLUGIN_TYPE *plugin_object_ptr)
{
	PionPluginPtr<PLUGIN_TYPE> plugin_ptr;
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	m_plugin_map.insert(std::make_pair(plugin_id,
									   std::make_pair(plugin_object_ptr, plugin_ptr)));
}

template <typename PLUGIN_TYPE>
inline void PluginManager<PLUGIN_TYPE>::remove(const std::string& plugin_id)
{
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::iterator i = m_plugin_map.find(plugin_id);
	if (i == m_plugin_map.end())
		throw PluginNotFoundException(plugin_id);
	if (i->second.second.is_open()) {
		i->second.second.destroy(i->second.first);
	} else {
		delete i->second.first;
	}
	m_plugin_map.erase(i);
}

template <typename PLUGIN_TYPE>
inline void PluginManager<PLUGIN_TYPE>::replace(const std::string& plugin_id, PLUGIN_TYPE *plugin_ptr)
{
	PION_ASSERT(plugin_ptr);
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::iterator i = m_plugin_map.find(plugin_id);
	if (i == m_plugin_map.end())
		throw PluginNotFoundException(plugin_id);
	if (i->second.second.is_open()) {
		i->second.second.destroy(i->second.first);
	} else {
		delete i->second.first;
	}
	i->second.first = plugin_ptr;
}

template <typename PLUGIN_TYPE>
inline PLUGIN_TYPE *PluginManager<PLUGIN_TYPE>::clone(const std::string& plugin_id)
{
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::iterator i = m_plugin_map.find(plugin_id);
	if (i == m_plugin_map.end())
		throw PluginNotFoundException(plugin_id);
	return i->second.second.create();
}

template <typename PLUGIN_TYPE>
inline PLUGIN_TYPE *PluginManager<PLUGIN_TYPE>::load(const std::string& plugin_id,
													 const std::string& plugin_type)
{
	// search for the plug-in file using the configured paths
	bool is_static;
	void *create_func;
	void *destroy_func;
	
	if (m_plugin_map.find(plugin_id) != m_plugin_map.end())
		throw DuplicatePluginException(plugin_id);
	
	// check if plug-in is statically linked, and if not, try to resolve for dynamic
	is_static = PionPlugin::findStaticEntryPoint(plugin_type, &create_func, &destroy_func);
	
	// open up the plug-in's shared object library
	PionPluginPtr<PLUGIN_TYPE> plugin_ptr;
	if (is_static) {
		plugin_ptr.openStaticLinked(plugin_type, create_func, destroy_func);	// may throw
	} else {
		plugin_ptr.open(plugin_type);	// may throw
	}
	
	// create a new object using the plug-in library
	PLUGIN_TYPE *plugin_object_ptr(plugin_ptr.create());
	
	// add the new plug-in object to our map
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	m_plugin_map.insert(std::make_pair(plugin_id,
									   std::make_pair(plugin_object_ptr, plugin_ptr)));

	return plugin_object_ptr;
}

template <typename PLUGIN_TYPE>
inline PLUGIN_TYPE *PluginManager<PLUGIN_TYPE>::get(const std::string& plugin_id)
{
	PLUGIN_TYPE *plugin_object_ptr = NULL;
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::iterator i = m_plugin_map.find(plugin_id);
	if (i != m_plugin_map.end())
		plugin_object_ptr = i->second.first;
	return plugin_object_ptr;
}
	
template <typename PLUGIN_TYPE>
inline const PLUGIN_TYPE *PluginManager<PLUGIN_TYPE>::get(const std::string& plugin_id) const
{
	const PLUGIN_TYPE *plugin_object_ptr = NULL;
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::const_iterator i = m_plugin_map.find(plugin_id);
	if (i != m_plugin_map.end())
		plugin_object_ptr = i->second.first;
	return plugin_object_ptr;
}
	
template <typename PLUGIN_TYPE>
inline PionPluginPtr<PLUGIN_TYPE> PluginManager<PLUGIN_TYPE>::getLibPtr(const std::string& plugin_id) const
{
	PionPluginPtr<PLUGIN_TYPE> plugin_ptr;
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::const_iterator i = m_plugin_map.find(plugin_id);
	if (i != m_plugin_map.end())
		plugin_ptr = i->second.second;
	return plugin_ptr;
}		

template <typename PLUGIN_TYPE>
inline PLUGIN_TYPE *PluginManager<PLUGIN_TYPE>::find(const std::string& resource)
{
	// will point to the matching plug-in object, if found
	PLUGIN_TYPE *plugin_object_ptr = NULL;
	
	// lock mutex for thread safety (this should probably use ref counters)
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	
	// check if no plug-ins are being managed
	if (m_plugin_map.empty()) return plugin_object_ptr;
	
	// iterate through each plug-in whose identifier may match the resource
	typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::iterator i = m_plugin_map.upper_bound(resource);
	while (i != m_plugin_map.begin()) {
		--i;
		
		// keep checking while the first part of the strings match
		if (resource.compare(0, i->first.size(), i->first) != 0) {
			// the first part no longer matches
			if (i != m_plugin_map.begin()) {
				// continue to next plug-in in list if its size is < this one
				typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::iterator j=i;
				--j;
				if (j->first.size() < i->first.size())
					continue;
			}
			// otherwise we've reached the end; stop looking for a match
			break;
		}
		
		// only if the resource matches the plug-in's identifier
		// or if resource is followed first with a '/' character
		if (resource.size() == i->first.size() || resource[i->first.size()]=='/') {
			plugin_object_ptr = i->second.first;
			break;
		}
	}
	
	return plugin_object_ptr;
}
	
template <typename PLUGIN_TYPE>
inline void PluginManager<PLUGIN_TYPE>::run(PluginRunFunction run_func)
{
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	for (typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::iterator i = m_plugin_map.begin();
		 i != m_plugin_map.end(); ++i)
	{
		run_func(i->second.first);
	}
}

template <typename PLUGIN_TYPE>
inline void PluginManager<PLUGIN_TYPE>::run(const std::string& plugin_id,
											PluginRunFunction run_func)
{
	// no need to lock (handled by PluginManager::get())
	PLUGIN_TYPE *plugin_object_ptr = get(plugin_id);
	if (plugin_object_ptr == NULL)
		throw PluginNotFoundException(plugin_id);
	run_func(plugin_object_ptr);
}

template <typename PLUGIN_TYPE>
inline boost::uint64_t PluginManager<PLUGIN_TYPE>::getStatistic(PluginStatFunction stat_func) const
{
	boost::uint64_t stat_value = 0;
	boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
	for (typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::const_iterator i = m_plugin_map.begin();
		 i != m_plugin_map.end(); ++i)
	{
		stat_value += stat_func(i->second.first);
	}
	return stat_value;
}

template <typename PLUGIN_TYPE>
inline boost::uint64_t PluginManager<PLUGIN_TYPE>::getStatistic(const std::string& plugin_id,
																PluginStatFunction stat_func) const
{
	// no need to lock (handled by PluginManager::get())
	const PLUGIN_TYPE *plugin_object_ptr = const_cast<PluginManager<PLUGIN_TYPE>*>(this)->get(plugin_id);
	if (plugin_object_ptr == NULL)
		throw PluginNotFoundException(plugin_id);
	return stat_func(plugin_object_ptr);
}


// PluginManager::PluginMap member functions

template <typename PLUGIN_TYPE>
inline void PluginManager<PLUGIN_TYPE>::PluginMap::clear(void)
{
	if (! std::map<std::string, std::pair<PLUGIN_TYPE *, PionPluginPtr<PLUGIN_TYPE> > >::empty()) {
		for (typename pion::PluginManager<PLUGIN_TYPE>::PluginMap::iterator i =
			 std::map<std::string, std::pair<PLUGIN_TYPE *, PionPluginPtr<PLUGIN_TYPE> > >::begin();
			 i != std::map<std::string, std::pair<PLUGIN_TYPE *, PionPluginPtr<PLUGIN_TYPE> > >::end(); ++i)
		{
			if (i->second.second.is_open()) {
				i->second.second.destroy(i->second.first);
			} else {
				delete i->second.first;
			}
		}
		erase(std::map<std::string, std::pair<PLUGIN_TYPE *, PionPluginPtr<PLUGIN_TYPE> > >::begin(),
			  std::map<std::string, std::pair<PLUGIN_TYPE *, PionPluginPtr<PLUGIN_TYPE> > >::end());
	}
}


}	// end namespace pion

#endif