This file is indexed.

/usr/include/pion/plugin_manager.hpp is in libpion-dev 5.0.4+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
// ---------------------------------------------------------------------
// pion:  a Boost C++ framework for building lightweight HTTP interfaces
// ---------------------------------------------------------------------
// Copyright (C) 2007-2012 Cloudmeter, Inc.  (http://www.cloudmeter.com)
//
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
//

#ifndef __PION_PLUGIN_MANAGER_HEADER__
#define __PION_PLUGIN_MANAGER_HEADER__

#include <map>
#include <string>
#include <boost/cstdint.hpp>
#include <boost/assert.hpp>
#include <boost/function.hpp>
#include <boost/function/function1.hpp>
#include <boost/thread/mutex.hpp>
#include <pion/config.hpp>
#include <pion/error.hpp>
#include <pion/plugin.hpp>


namespace pion {    // begin namespace pion

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

    /// data type for a function that may be called by the run() method
    typedef boost::function1<void, PluginType*>    PluginRunFunction;

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

    
    /// default constructor
    plugin_manager(void) {}

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

    /// 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, PluginType *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, PluginType *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 PluginType* pointer to the new plug-in object
     */
    inline PluginType *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 PluginType* pointer to the new plug-in object
     */
    inline PluginType *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 PluginType* pointer to the matching plug-in object or NULL if not found
     */
    inline PluginType *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 PluginType* pointer to the matching plug-in object or NULL if not found
     */
    inline const PluginType *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 plugin_ptr<PluginType> pointer to the plugin shared library if found
     */
    inline plugin_ptr<PluginType> get_lib_ptr(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 PluginType* pointer to the matching plug-in object or NULL if not found
     */
    inline PluginType *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 get_statistic(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 get_statistic(const std::string& plugin_id,
                                        PluginStatFunction stat_func) const;
        
    
protected:
    
    /// data type that maps identifiers to plug-in objects
    class map_type
        : public std::map<std::string, std::pair<PluginType *, plugin_ptr<PluginType> > >
    {
    public:
        inline void clear(void);
        virtual ~map_type() { map_type::clear(); }
        map_type(void) {}
    };
    
    /// collection of plug-in objects being managed
    map_type                m_plugin_map;

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

    
// plugin_manager member functions

template <typename PluginType>
inline void plugin_manager<PluginType>::add(const std::string& plugin_id,
                                            PluginType *plugin_object_ptr)
{
    plugin_ptr<PluginType> 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 PluginType>
inline void plugin_manager<PluginType>::remove(const std::string& plugin_id)
{
    boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
    typename pion::plugin_manager<PluginType>::map_type::iterator i = m_plugin_map.find(plugin_id);
    if (i == m_plugin_map.end())
        BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(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 PluginType>
inline void plugin_manager<PluginType>::replace(const std::string& plugin_id, PluginType *plugin_ptr)
{
    BOOST_ASSERT(plugin_ptr);
    boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
    typename pion::plugin_manager<PluginType>::map_type::iterator i = m_plugin_map.find(plugin_id);
    if (i == m_plugin_map.end())
        BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(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 PluginType>
inline PluginType *plugin_manager<PluginType>::clone(const std::string& plugin_id)
{
    boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
    typename pion::plugin_manager<PluginType>::map_type::iterator i = m_plugin_map.find(plugin_id);
    if (i == m_plugin_map.end())
        BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(plugin_id) );
    return i->second.second.create();
}

template <typename PluginType>
inline PluginType *plugin_manager<PluginType>::load(const std::string& plugin_id,
                                                     const std::string& plugin_type)
{
    // search for the plug-in file using the configured paths
    if (m_plugin_map.find(plugin_id) != m_plugin_map.end())
        BOOST_THROW_EXCEPTION( error::duplicate_plugin() << error::errinfo_plugin_name(plugin_id) );
    
    // open up the plug-in's shared object library
    plugin_ptr<PluginType> plugin_ptr;
    plugin_ptr.open(plugin_type);   // may throw
    
    // create a new object using the plug-in library
    PluginType *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 PluginType>
inline PluginType *plugin_manager<PluginType>::get(const std::string& plugin_id)
{
    PluginType *plugin_object_ptr = NULL;
    boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
    typename pion::plugin_manager<PluginType>::map_type::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 PluginType>
inline const PluginType *plugin_manager<PluginType>::get(const std::string& plugin_id) const
{
    const PluginType *plugin_object_ptr = NULL;
    boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
    typename pion::plugin_manager<PluginType>::map_type::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 PluginType>
inline plugin_ptr<PluginType> plugin_manager<PluginType>::get_lib_ptr(const std::string& plugin_id) const
{
    plugin_ptr<PluginType> plugin_ptr;
    boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
    typename pion::plugin_manager<PluginType>::map_type::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 PluginType>
inline PluginType *plugin_manager<PluginType>::find(const std::string& resource)
{
    // will point to the matching plug-in object, if found
    PluginType *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::plugin_manager<PluginType>::map_type::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::plugin_manager<PluginType>::map_type::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 PluginType>
inline void plugin_manager<PluginType>::run(PluginRunFunction run_func)
{
    boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
    for (typename pion::plugin_manager<PluginType>::map_type::iterator i = m_plugin_map.begin();
         i != m_plugin_map.end(); ++i)
    {
        run_func(i->second.first);
    }
}

template <typename PluginType>
inline void plugin_manager<PluginType>::run(const std::string& plugin_id,
                                            PluginRunFunction run_func)
{
    // no need to lock (handled by plugin_manager::get())
    PluginType *plugin_object_ptr = get(plugin_id);
    if (plugin_object_ptr == NULL)
        BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(plugin_id) );
    run_func(plugin_object_ptr);
}

template <typename PluginType>
inline boost::uint64_t plugin_manager<PluginType>::get_statistic(PluginStatFunction stat_func) const
{
    boost::uint64_t stat_value = 0;
    boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
    for (typename pion::plugin_manager<PluginType>::map_type::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 PluginType>
inline boost::uint64_t plugin_manager<PluginType>::get_statistic(const std::string& plugin_id,
                                                                PluginStatFunction stat_func) const
{
    // no need to lock (handled by plugin_manager::get())
    const PluginType *plugin_object_ptr = const_cast<plugin_manager<PluginType>*>(this)->get(plugin_id);
    if (plugin_object_ptr == NULL)
        BOOST_THROW_EXCEPTION( error::plugin_not_found() << error::errinfo_plugin_name(plugin_id) );
    return stat_func(plugin_object_ptr);
}


// plugin_manager::map_type member functions

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


}   // end namespace pion

#endif