Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

algparam.h

00001 #ifndef CRYPTOPP_ALGPARAM_H
00002 #define CRYPTOPP_ALGPARAM_H
00003 
00004 #include "cryptlib.h"
00005 #include "smartptr.h"
00006 #include "secblock.h"
00007 
00008 NAMESPACE_BEGIN(CryptoPP)
00009 
00010 //! used to pass byte array input as part of a NameValuePairs object
00011 /*! the deepCopy option is used when the NameValuePairs object can't
00012         keep a copy of the data available */
00013 class ConstByteArrayParameter
00014 {
00015 public:
00016         ConstByteArrayParameter(const char *data = NULL, bool deepCopy = false)
00017         {
00018                 Assign((const byte *)data, data ? strlen(data) : 0, deepCopy);
00019         }
00020         ConstByteArrayParameter(const byte *data, unsigned int size, bool deepCopy = false)
00021         {
00022                 Assign(data, size, deepCopy);
00023         }
00024         template <class T> ConstByteArrayParameter(const T &string, bool deepCopy = false)
00025         {
00026                 CRYPTOPP_COMPILE_ASSERT(sizeof(string[0])==1);
00027                 Assign((const byte *)string.data(), string.size(), deepCopy);
00028         }
00029 
00030         void Assign(const byte *data, unsigned int size, bool deepCopy)
00031         {
00032                 if (deepCopy)
00033                         m_block.Assign(data, size);
00034                 else
00035                 {
00036                         m_data = data;
00037                         m_size = size;
00038                 }
00039                 m_deepCopy = deepCopy;
00040         }
00041 
00042         const byte *begin() const {return m_deepCopy ? m_block.begin() : m_data;}
00043         const byte *end() const {return m_deepCopy ? m_block.end() : m_data + m_size;}
00044         unsigned int size() const {return m_deepCopy ? m_block.size() : m_size;}
00045 
00046 private:
00047         bool m_deepCopy;
00048         const byte *m_data;
00049         unsigned int m_size;
00050         SecByteBlock m_block;
00051 };
00052 
00053 class ByteArrayParameter
00054 {
00055 public:
00056         ByteArrayParameter(byte *data = NULL, unsigned int size = 0)
00057                 : m_data(data), m_size(size) {}
00058         ByteArrayParameter(SecByteBlock &block)
00059                 : m_data(block.begin()), m_size(block.size()) {}
00060 
00061         byte *begin() const {return m_data;}
00062         byte *end() const {return m_data + m_size;}
00063         unsigned int size() const {return m_size;}
00064 
00065 private:
00066         byte *m_data;
00067         unsigned int m_size;
00068 };
00069 
00070 class CombinedNameValuePairs : public NameValuePairs
00071 {
00072 public:
00073         CombinedNameValuePairs(const NameValuePairs &pairs1, const NameValuePairs &pairs2)
00074                 : m_pairs1(pairs1), m_pairs2(pairs2) {}
00075 
00076         bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00077         {
00078                 if (strcmp(name, "ValueNames") == 0)
00079                         return m_pairs1.GetVoidValue(name, valueType, pValue) && m_pairs2.GetVoidValue(name, valueType, pValue);
00080                 else
00081                         return m_pairs1.GetVoidValue(name, valueType, pValue) || m_pairs2.GetVoidValue(name, valueType, pValue);
00082         }
00083 
00084         const NameValuePairs &m_pairs1, &m_pairs2;
00085 };
00086 
00087 template <class T, class BASE>
00088 class GetValueHelperClass
00089 {
00090 public:
00091         GetValueHelperClass(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst)
00092                 : m_pObject(pObject), m_name(name), m_valueType(&valueType), m_pValue(pValue), m_found(false), m_getValueNames(false)
00093         {
00094                 if (strcmp(m_name, "ValueNames") == 0)
00095                 {
00096                         m_found = m_getValueNames = true;
00097                         NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(std::string), *m_valueType);
00098                         if (searchFirst)
00099                                 searchFirst->GetVoidValue(m_name, valueType, pValue);
00100                         if (typeid(T) != typeid(BASE))
00101                                 pObject->BASE::GetVoidValue(m_name, valueType, pValue);
00102                         ((*reinterpret_cast<std::string *>(m_pValue) += "ThisPointer:") += typeid(T).name()) += ';';
00103                 }
00104 
00105                 if (!m_found && strncmp(m_name, "ThisPointer:", 12) == 0 && strcmp(m_name+12, typeid(T).name()) == 0)
00106                 {
00107                         NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T *), *m_valueType);
00108                         *reinterpret_cast<const T **>(pValue) = pObject;
00109                         m_found = true;
00110                         return;
00111                 }
00112 
00113                 if (!m_found && searchFirst)
00114                         m_found = searchFirst->GetVoidValue(m_name, valueType, pValue);
00115                 
00116                 if (!m_found && typeid(T) != typeid(BASE))
00117                         m_found = pObject->BASE::GetVoidValue(m_name, valueType, pValue);
00118         }
00119 
00120         operator bool() const {return m_found;}
00121 
00122         template <class R>
00123         GetValueHelperClass<T,BASE> & operator()(const char *name, const R & (T::*pm)() const)
00124         {
00125                 if (m_getValueNames)
00126                         (*reinterpret_cast<std::string *>(m_pValue) += name) += ";";
00127                 if (!m_found && strcmp(name, m_name) == 0)
00128                 {
00129                         NameValuePairs::ThrowIfTypeMismatch(name, typeid(R), *m_valueType);
00130                         *reinterpret_cast<R *>(m_pValue) = (m_pObject->*pm)();
00131                         m_found = true;
00132                 }
00133                 return *this;
00134         }
00135 
00136         GetValueHelperClass<T,BASE> &Assignable()
00137         {
00138                 if (m_getValueNames)
00139                         ((*reinterpret_cast<std::string *>(m_pValue) += "ThisObject:") += typeid(T).name()) += ';';
00140                 if (!m_found && strncmp(m_name, "ThisObject:", 11) == 0 && strcmp(m_name+11, typeid(T).name()) == 0)
00141                 {
00142                         NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T), *m_valueType);
00143                         *reinterpret_cast<T *>(m_pValue) = *m_pObject;
00144                         m_found = true;
00145                 }
00146                 return *this;
00147         }
00148 
00149 private:
00150         const T *m_pObject;
00151         const char *m_name;
00152         const std::type_info *m_valueType;
00153         void *m_pValue;
00154         bool m_found, m_getValueNames;
00155 };
00156 
00157 template <class BASE, class T>
00158 GetValueHelperClass<T, BASE> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL, BASE *dummy=NULL)
00159 {
00160         return GetValueHelperClass<T, BASE>(pObject, name, valueType, pValue, searchFirst);
00161 }
00162 
00163 template <class T>
00164 GetValueHelperClass<T, T> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL)
00165 {
00166         return GetValueHelperClass<T, T>(pObject, name, valueType, pValue, searchFirst);
00167 }
00168 
00169 // ********************************************************
00170 
00171 template <class R>
00172 R Hack_DefaultValueFromConstReferenceType(const R &)
00173 {
00174         return R();
00175 }
00176 
00177 template <class R>
00178 bool Hack_GetValueIntoConstReference(const NameValuePairs &source, const char *name, const R &value)
00179 {
00180         return source.GetValue(name, const_cast<R &>(value));
00181 }
00182 
00183 template <class T, class BASE>
00184 class AssignFromHelperClass
00185 {
00186 public:
00187         AssignFromHelperClass(T *pObject, const NameValuePairs &source)
00188                 : m_pObject(pObject), m_source(source), m_done(false)
00189         {
00190                 if (source.GetThisObject(*pObject))
00191                         m_done = true;
00192                 else if (typeid(BASE) != typeid(T))
00193                         pObject->BASE::AssignFrom(source);
00194         }
00195 
00196         template <class R>
00197         AssignFromHelperClass & operator()(const char *name, void (T::*pm)(R))  // VC60 workaround: "const R &" here causes compiler error
00198         {
00199                 if (!m_done)
00200                 {
00201                         R value = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<R>(*(int *)NULL));
00202                         if (!Hack_GetValueIntoConstReference(m_source, name, value))
00203                                 throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name + "'");
00204                         (m_pObject->*pm)(value);
00205                 }
00206                 return *this;
00207         }
00208 
00209         template <class R, class S>
00210         AssignFromHelperClass & operator()(const char *name1, const char *name2, void (T::*pm)(R, S))   // VC60 workaround: "const R &" here causes compiler error
00211         {
00212                 if (!m_done)
00213                 {
00214                         R value1 = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<R>(*(int *)NULL));
00215                         if (!Hack_GetValueIntoConstReference(m_source, name1, value1))
00216                                 throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name1 + "'");
00217                         S value2 = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<S>(*(int *)NULL));
00218                         if (!Hack_GetValueIntoConstReference(m_source, name2, value2))
00219                                 throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name2 + "'");
00220                         (m_pObject->*pm)(value1, value2);
00221                 }
00222                 return *this;
00223         }
00224 
00225 private:
00226         T *m_pObject;
00227         const NameValuePairs &m_source;
00228         bool m_done;
00229 };
00230 
00231 template <class BASE, class T>
00232 AssignFromHelperClass<T, BASE> AssignFromHelper(T *pObject, const NameValuePairs &source, BASE *dummy=NULL)
00233 {
00234         return AssignFromHelperClass<T, BASE>(pObject, source);
00235 }
00236 
00237 template <class T>
00238 AssignFromHelperClass<T, T> AssignFromHelper(T *pObject, const NameValuePairs &source)
00239 {
00240         return AssignFromHelperClass<T, T>(pObject, source);
00241 }
00242 
00243 // ********************************************************
00244 
00245 // This should allow the linker to discard Integer code if not needed.
00246 extern bool (*AssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt);
00247 
00248 const std::type_info & IntegerTypeId();
00249 
00250 template <class BASE, class T>
00251 class AlgorithmParameters : public NameValuePairs
00252 {
00253 public:
00254         AlgorithmParameters(const BASE &base, const char *name, const T &value)
00255                 : m_base(base), m_name(name), m_value(value)
00256 #ifndef NDEBUG
00257                 , m_used(false)
00258 #endif
00259         {}
00260 
00261 #ifndef NDEBUG
00262         AlgorithmParameters(const AlgorithmParameters &copy)
00263                 : m_base(copy.m_base), m_name(copy.m_name), m_value(copy.m_value), m_used(false)
00264         {
00265                 copy.m_used = true;
00266         }
00267 
00268         // TODO: revisit after implementing some tracing mechanism, this won't work because of exceptions
00269 //      ~AlgorithmParameters() {assert(m_used);}        // use assert here because we don't want to throw out of a destructor
00270 #endif
00271 
00272         template <class R>
00273         AlgorithmParameters<AlgorithmParameters<BASE,T>, R> operator()(const char *name, const R &value) const
00274         {
00275                 return AlgorithmParameters<AlgorithmParameters<BASE,T>, R>(*this, name, value);
00276         }
00277 
00278         bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00279         {
00280                 if (strcmp(name, "ValueNames") == 0)
00281                 {
00282                         ThrowIfTypeMismatch(name, typeid(std::string), valueType);
00283                         m_base.GetVoidValue(name, valueType, pValue);
00284                         (*reinterpret_cast<std::string *>(pValue) += m_name) += ";";
00285                         return true;
00286                 }
00287                 else if (strcmp(name, m_name) == 0)
00288                 {
00289                         // special case for retrieving an Integer parameter when an int was passed in
00290                         if (!(AssignIntToInteger != NULL && typeid(T) == typeid(int) && AssignIntToInteger(valueType, pValue, &m_value)))
00291                         {
00292                                 ThrowIfTypeMismatch(name, typeid(T), valueType);
00293                                 *reinterpret_cast<T *>(pValue) = m_value;
00294                         }
00295 #ifndef NDEBUG
00296                         m_used = true;
00297 #endif
00298                         return true;
00299                 }
00300                 else
00301                         return m_base.GetVoidValue(name, valueType, pValue);
00302         }
00303 
00304 private:
00305         BASE m_base;
00306         const char *m_name;
00307         T m_value;
00308 #ifndef NDEBUG
00309         mutable bool m_used;
00310 #endif
00311 };
00312 
00313 template <class T>
00314 AlgorithmParameters<NullNameValuePairs,T> MakeParameters(const char *name, const T &value)
00315 {
00316         return AlgorithmParameters<NullNameValuePairs,T>(g_nullNameValuePairs, name, value);
00317 }
00318 
00319 #define CRYPTOPP_GET_FUNCTION_ENTRY(name)               (Name::name(), &ThisClass::Get##name)
00320 #define CRYPTOPP_SET_FUNCTION_ENTRY(name)               (Name::name(), &ThisClass::Set##name)
00321 #define CRYPTOPP_SET_FUNCTION_ENTRY2(name1, name2)      (Name::name1(), Name::name2(), &ThisClass::Set##name1##And##name2)
00322 
00323 NAMESPACE_END
00324 
00325 #endif

Generated on Sun Mar 14 20:44:24 2004 for Crypto++ by doxygen 1.3.6-20040222