Crypto++
factory.h
1 #ifndef CRYPTOPP_OBJFACT_H
2 #define CRYPTOPP_OBJFACT_H
3 
4 #include "cryptlib.h"
5 #include <map>
6 #include <vector>
7 
8 NAMESPACE_BEGIN(CryptoPP)
9 
10 //! _
11 template <class AbstractClass>
13 {
14 public:
15  virtual ~ObjectFactory () {}
16  virtual AbstractClass * CreateObject() const =0;
17 };
18 
19 //! _
20 template <class AbstractClass, class ConcreteClass>
21 class DefaultObjectFactory : public ObjectFactory<AbstractClass>
22 {
23 public:
24  AbstractClass * CreateObject() const
25  {
26  return new ConcreteClass;
27  }
28 
29 };
30 
31 //! _
32 template <class AbstractClass, int instance=0>
34 {
35 public:
36  class FactoryNotFound : public Exception
37  {
38  public:
39  FactoryNotFound(const char *name) : Exception(OTHER_ERROR, std::string("ObjectFactoryRegistry: could not find factory for algorithm ") + name) {}
40  };
41 
43  {
44  for (CPP_TYPENAME Map::iterator i = m_map.begin(); i != m_map.end(); ++i)
45  {
46  delete (ObjectFactory<AbstractClass> *)i->second;
47  i->second = NULL;
48  }
49  }
50 
51  void RegisterFactory(const std::string &name, ObjectFactory<AbstractClass> *factory)
52  {
53  m_map[name] = factory;
54  }
55 
56  const ObjectFactory<AbstractClass> * GetFactory(const char *name) const
57  {
58  CPP_TYPENAME Map::const_iterator i = m_map.find(name);
59  return i == m_map.end() ? NULL : (ObjectFactory<AbstractClass> *)i->second;
60  }
61 
62  AbstractClass *CreateObject(const char *name) const
63  {
64  const ObjectFactory<AbstractClass> *factory = GetFactory(name);
65  if (!factory)
66  throw FactoryNotFound(name);
67  return factory->CreateObject();
68  }
69 
70  // Return a vector containing the factory names. This is easier than returning an iterator.
71  // from Andrew Pitonyak
72  std::vector<std::string> GetFactoryNames() const
73  {
74  std::vector<std::string> names;
75  CPP_TYPENAME Map::const_iterator iter;
76  for (iter = m_map.begin(); iter != m_map.end(); ++iter)
77  names.push_back(iter->first);
78  return names;
79  }
80 
81  CRYPTOPP_NOINLINE static ObjectFactoryRegistry<AbstractClass, instance> & Registry(CRYPTOPP_NOINLINE_DOTDOTDOT);
82 
83 private:
84  // use void * instead of ObjectFactory<AbstractClass> * to save code size
85  typedef std::map<std::string, void *> Map;
86  Map m_map;
87 };
88 
89 template <class AbstractClass, int instance>
91 {
93  return s_registry;
94 }
95 
96 template <class AbstractClass, class ConcreteClass, int instance = 0>
98 RegisterDefaultFactoryFor(const char *name=NULL)
99 {
100  // BCB2006 workaround
101  std::string n = name ? std::string(name) : std::string(ConcreteClass::StaticAlgorithmName());
104 }};
105 
106 template <class SchemeClass>
107 void RegisterAsymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL)
108 {
111 }
112 
113 template <class SchemeClass>
114 void RegisterSignatureSchemeDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL)
115 {
118 }
119 
120 template <class SchemeClass>
121 void RegisterSymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL)
122 {
125 }
126 
127 template <class SchemeClass>
128 void RegisterAuthenticatedSymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL)
129 {
132 }
133 
134 NAMESPACE_END
135 
136 #endif