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 Wed Jul 28 08:07:06 2004 for Crypto++ by doxygen 1.3.7