File indexing completed on 2025-01-18 09:54:53
0001
0002
0003
0004
0005
0006 #ifndef CRYPTOPP_ALGPARAM_H
0007 #define CRYPTOPP_ALGPARAM_H
0008
0009 #include "config.h"
0010 #include "cryptlib.h"
0011
0012 #include "smartptr.h"
0013 #include "secblock.h"
0014 #include "integer.h"
0015 #include "misc.h"
0016
0017 #include <string>
0018 #include <typeinfo>
0019 #include <exception>
0020
0021 NAMESPACE_BEGIN(CryptoPP)
0022
0023
0024 class ConstByteArrayParameter
0025 {
0026 public:
0027
0028
0029
0030
0031
0032 ConstByteArrayParameter(const char *data = NULLPTR, bool deepCopy = false)
0033 : m_deepCopy(false), m_data(NULLPTR), m_size(0)
0034 {
0035 Assign(reinterpret_cast<const byte *>(data), data ? strlen(data) : 0, deepCopy);
0036 }
0037
0038
0039
0040
0041
0042
0043
0044 ConstByteArrayParameter(const byte *data, size_t size, bool deepCopy = false)
0045 : m_deepCopy(false), m_data(NULLPTR), m_size(0)
0046 {
0047 Assign(data, size, deepCopy);
0048 }
0049
0050
0051
0052
0053
0054
0055
0056 template <class T> ConstByteArrayParameter(const T &string, bool deepCopy = false)
0057 : m_deepCopy(false), m_data(NULLPTR), m_size(0)
0058 {
0059 CRYPTOPP_COMPILE_ASSERT(sizeof(typename T::value_type) == 1);
0060 Assign(reinterpret_cast<const byte *>(&string[0]), string.size(), deepCopy);
0061 }
0062
0063
0064
0065
0066
0067
0068
0069 void Assign(const byte *data, size_t size, bool deepCopy)
0070 {
0071
0072
0073 if (deepCopy)
0074 m_block.Assign(data, size);
0075 else
0076 {
0077 m_data = data;
0078 m_size = size;
0079 }
0080 m_deepCopy = deepCopy;
0081 }
0082
0083
0084 const byte *begin() const {return m_deepCopy ? m_block.begin() : m_data;}
0085
0086 const byte *end() const {return m_deepCopy ? m_block.end() : m_data + m_size;}
0087
0088 size_t size() const {return m_deepCopy ? m_block.size() : m_size;}
0089
0090 private:
0091 bool m_deepCopy;
0092 const byte *m_data;
0093 size_t m_size;
0094 SecByteBlock m_block;
0095 };
0096
0097
0098 class ByteArrayParameter
0099 {
0100 public:
0101
0102
0103
0104 ByteArrayParameter(byte *data = NULLPTR, unsigned int size = 0)
0105 : m_data(data), m_size(size) {}
0106
0107
0108
0109 ByteArrayParameter(SecByteBlock &block)
0110 : m_data(block.begin()), m_size(block.size()) {}
0111
0112
0113 byte *begin() const {return m_data;}
0114
0115 byte *end() const {return m_data + m_size;}
0116
0117 size_t size() const {return m_size;}
0118
0119 private:
0120 byte *m_data;
0121 size_t m_size;
0122 };
0123
0124
0125
0126
0127
0128 class CRYPTOPP_DLL CombinedNameValuePairs : public NameValuePairs
0129 {
0130 public:
0131
0132
0133
0134 CombinedNameValuePairs(const NameValuePairs &pairs1, const NameValuePairs &pairs2)
0135 : m_pairs1(pairs1), m_pairs2(pairs2) {}
0136
0137 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
0138
0139 private:
0140 const NameValuePairs &m_pairs1, &m_pairs2;
0141 };
0142
0143 #ifndef CRYPTOPP_DOXYGEN_PROCESSING
0144 template <class T, class BASE>
0145 class GetValueHelperClass
0146 {
0147 public:
0148 GetValueHelperClass(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst)
0149 : m_pObject(pObject), m_name(name), m_valueType(&valueType), m_pValue(pValue), m_found(false), m_getValueNames(false)
0150 {
0151 if (strcmp(m_name, "ValueNames") == 0)
0152 {
0153 m_found = m_getValueNames = true;
0154 NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(std::string), *m_valueType);
0155 if (searchFirst)
0156 searchFirst->GetVoidValue(m_name, valueType, pValue);
0157 if (typeid(T) != typeid(BASE))
0158 pObject->BASE::GetVoidValue(m_name, valueType, pValue);
0159 ((*reinterpret_cast<std::string *>(m_pValue) += "ThisPointer:") += typeid(T).name()) += ';';
0160 }
0161
0162 if (!m_found && strncmp(m_name, "ThisPointer:", 12) == 0 && strcmp(m_name+12, typeid(T).name()) == 0)
0163 {
0164 NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T *), *m_valueType);
0165 *reinterpret_cast<const T **>(pValue) = pObject;
0166 m_found = true;
0167 return;
0168 }
0169
0170 if (!m_found && searchFirst)
0171 m_found = searchFirst->GetVoidValue(m_name, valueType, pValue);
0172
0173 if (!m_found && typeid(T) != typeid(BASE))
0174 m_found = pObject->BASE::GetVoidValue(m_name, valueType, pValue);
0175 }
0176
0177 operator bool() const {return m_found;}
0178
0179 template <class R>
0180 GetValueHelperClass<T,BASE> & operator()(const char *name, const R & (T::*pm)() const)
0181 {
0182 if (m_getValueNames)
0183 (*reinterpret_cast<std::string *>(m_pValue) += name) += ";";
0184 if (!m_found && strcmp(name, m_name) == 0)
0185 {
0186 NameValuePairs::ThrowIfTypeMismatch(name, typeid(R), *m_valueType);
0187 *reinterpret_cast<R *>(m_pValue) = (m_pObject->*pm)();
0188 m_found = true;
0189 }
0190 return *this;
0191 }
0192
0193 GetValueHelperClass<T,BASE> &Assignable()
0194 {
0195 #ifndef __INTEL_COMPILER
0196 if (m_getValueNames)
0197 ((*reinterpret_cast<std::string *>(m_pValue) += "ThisObject:") += typeid(T).name()) += ';';
0198 if (!m_found && strncmp(m_name, "ThisObject:", 11) == 0 && strcmp(m_name+11, typeid(T).name()) == 0)
0199 {
0200 NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T), *m_valueType);
0201 *reinterpret_cast<T *>(m_pValue) = *m_pObject;
0202 m_found = true;
0203 }
0204 #endif
0205 return *this;
0206 }
0207
0208 private:
0209 const T *m_pObject;
0210 const char *m_name;
0211 const std::type_info *m_valueType;
0212 void *m_pValue;
0213 bool m_found, m_getValueNames;
0214 };
0215
0216 template <class BASE, class T>
0217 GetValueHelperClass<T, BASE> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULLPTR)
0218 {
0219 return GetValueHelperClass<T, BASE>(pObject, name, valueType, pValue, searchFirst);
0220 }
0221
0222 template <class T>
0223 GetValueHelperClass<T, T> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULLPTR)
0224 {
0225 return GetValueHelperClass<T, T>(pObject, name, valueType, pValue, searchFirst);
0226 }
0227
0228
0229
0230 template <class T, class BASE>
0231 class AssignFromHelperClass
0232 {
0233 public:
0234 AssignFromHelperClass(T *pObject, const NameValuePairs &source)
0235 : m_pObject(pObject), m_source(source), m_done(false)
0236 {
0237 if (source.GetThisObject(*pObject))
0238 m_done = true;
0239 else if (typeid(BASE) != typeid(T))
0240 pObject->BASE::AssignFrom(source);
0241 }
0242
0243 template <class R>
0244 AssignFromHelperClass & operator()(const char *name, void (T::*pm)(const R&))
0245 {
0246 if (!m_done)
0247 {
0248 R value;
0249 if (!m_source.GetValue(name, value))
0250 throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name + "'");
0251 (m_pObject->*pm)(value);
0252 }
0253 return *this;
0254 }
0255
0256 template <class R, class S>
0257 AssignFromHelperClass & operator()(const char *name1, const char *name2, void (T::*pm)(const R&, const S&))
0258 {
0259 if (!m_done)
0260 {
0261 R value1;
0262 if (!m_source.GetValue(name1, value1))
0263 throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name1 + "'");
0264 S value2;
0265 if (!m_source.GetValue(name2, value2))
0266 throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name2 + "'");
0267 (m_pObject->*pm)(value1, value2);
0268 }
0269 return *this;
0270 }
0271
0272 private:
0273 T *m_pObject;
0274 const NameValuePairs &m_source;
0275 bool m_done;
0276 };
0277
0278 template <class BASE, class T>
0279 AssignFromHelperClass<T, BASE> AssignFromHelper(T *pObject, const NameValuePairs &source)
0280 {
0281 return AssignFromHelperClass<T, BASE>(pObject, source);
0282 }
0283
0284 template <class T>
0285 AssignFromHelperClass<T, T> AssignFromHelper(T *pObject, const NameValuePairs &source)
0286 {
0287 return AssignFromHelperClass<T, T>(pObject, source);
0288 }
0289
0290 #endif
0291
0292
0293
0294 #ifndef CRYPTOPP_NO_ASSIGN_TO_INTEGER
0295
0296
0297 CRYPTOPP_DLL bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt);
0298 #endif
0299
0300 CRYPTOPP_DLL const std::type_info & CRYPTOPP_API IntegerTypeId();
0301
0302
0303 class CRYPTOPP_DLL AlgorithmParametersBase
0304 {
0305 public:
0306
0307 class ParameterNotUsed : public Exception
0308 {
0309 public:
0310 ParameterNotUsed(const char *name) : Exception(OTHER_ERROR, std::string("AlgorithmParametersBase: parameter \"") + name + "\" not used") {}
0311 };
0312
0313 virtual ~AlgorithmParametersBase() CRYPTOPP_THROW
0314 {
0315
0316 #if defined(CRYPTOPP_CXX17_UNCAUGHT_EXCEPTIONS)
0317 if (std::uncaught_exceptions() == 0)
0318 #elif defined(CRYPTOPP_CXX98_UNCAUGHT_EXCEPTION)
0319 if (std::uncaught_exception() == false)
0320 #else
0321 try
0322 #endif
0323 {
0324 if (m_throwIfNotUsed && !m_used)
0325 throw ParameterNotUsed(m_name);
0326 }
0327 #if !defined(CRYPTOPP_CXX98_UNCAUGHT_EXCEPTION)
0328 # if !defined(CRYPTOPP_CXX17_UNCAUGHT_EXCEPTIONS)
0329 catch(const Exception&)
0330 {
0331 }
0332 # endif
0333 #endif
0334 }
0335
0336
0337 AlgorithmParametersBase(const AlgorithmParametersBase &x)
0338 : m_name(x.m_name), m_throwIfNotUsed(x.m_throwIfNotUsed), m_used(x.m_used)
0339 {
0340 m_next.reset(const_cast<AlgorithmParametersBase &>(x).m_next.release());
0341 x.m_used = true;
0342 }
0343
0344
0345
0346
0347
0348
0349 AlgorithmParametersBase(const char *name, bool throwIfNotUsed)
0350 : m_name(name), m_throwIfNotUsed(throwIfNotUsed), m_used(false) {}
0351
0352 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
0353
0354 protected:
0355 friend class AlgorithmParameters;
0356 void operator=(const AlgorithmParametersBase& rhs);
0357
0358 virtual void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const =0;
0359 virtual void MoveInto(void *p) const =0;
0360
0361 const char *m_name;
0362 bool m_throwIfNotUsed;
0363 mutable bool m_used;
0364 member_ptr<AlgorithmParametersBase> m_next;
0365 };
0366
0367
0368
0369 template <class T>
0370 class AlgorithmParametersTemplate : public AlgorithmParametersBase
0371 {
0372 public:
0373
0374
0375
0376
0377
0378
0379 AlgorithmParametersTemplate(const char *name, const T &value, bool throwIfNotUsed)
0380 : AlgorithmParametersBase(name, throwIfNotUsed), m_value(value)
0381 {
0382 }
0383
0384 void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const
0385 {
0386 #ifndef CRYPTOPP_NO_ASSIGN_TO_INTEGER
0387
0388 if (!(typeid(T) == typeid(int) && AssignIntToInteger(valueType, pValue, &m_value)))
0389 #endif
0390 {
0391 NameValuePairs::ThrowIfTypeMismatch(name, typeid(T), valueType);
0392 *reinterpret_cast<T *>(pValue) = m_value;
0393 }
0394 }
0395
0396 #if defined(DEBUG_NEW) && (CRYPTOPP_MSC_VERSION >= 1300)
0397 # pragma push_macro("new")
0398 # undef new
0399 #endif
0400
0401 void MoveInto(void *buffer) const
0402 {
0403 AlgorithmParametersTemplate<T>* p = new(buffer) AlgorithmParametersTemplate<T>(*this);
0404 CRYPTOPP_UNUSED(p);
0405 }
0406
0407 #if defined(DEBUG_NEW) && (CRYPTOPP_MSC_VERSION >= 1300)
0408 # pragma pop_macro("new")
0409 #endif
0410
0411 protected:
0412 T m_value;
0413 };
0414
0415 CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<bool>;
0416 CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<int>;
0417 CRYPTOPP_DLL_TEMPLATE_CLASS AlgorithmParametersTemplate<ConstByteArrayParameter>;
0418
0419
0420
0421
0422
0423
0424
0425 class CRYPTOPP_DLL AlgorithmParameters : public NameValuePairs
0426 {
0427 public:
0428
0429
0430
0431
0432
0433
0434 AlgorithmParameters();
0435
0436 #ifdef __BORLANDC__
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 template <class T>
0450 AlgorithmParameters(const char *name, const T &value, bool throwIfNotUsed=true)
0451 : m_next(new AlgorithmParametersTemplate<T>(name, value, throwIfNotUsed))
0452 , m_defaultThrowIfNotUsed(throwIfNotUsed)
0453 {
0454 }
0455 #endif
0456
0457 AlgorithmParameters(const AlgorithmParameters &x);
0458
0459 AlgorithmParameters & operator=(const AlgorithmParameters &x);
0460
0461
0462
0463
0464
0465 template <class T>
0466 AlgorithmParameters & operator()(const char *name, const T &value, bool throwIfNotUsed)
0467 {
0468 member_ptr<AlgorithmParametersBase> p(new AlgorithmParametersTemplate<T>(name, value, throwIfNotUsed));
0469 p->m_next.reset(m_next.release());
0470 m_next.reset(p.release());
0471 m_defaultThrowIfNotUsed = throwIfNotUsed;
0472 return *this;
0473 }
0474
0475
0476
0477
0478
0479 template <class T>
0480 AlgorithmParameters & operator()(const char *name, const T &value)
0481 {
0482 return operator()(name, value, m_defaultThrowIfNotUsed);
0483 }
0484
0485 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
0486
0487 protected:
0488 member_ptr<AlgorithmParametersBase> m_next;
0489 bool m_defaultThrowIfNotUsed;
0490 };
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504 #ifdef __BORLANDC__
0505 typedef AlgorithmParameters MakeParameters;
0506 #else
0507 template <class T>
0508 AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed = true)
0509 {
0510 return AlgorithmParameters()(name, value, throwIfNotUsed);
0511 }
0512 #endif
0513
0514 #define CRYPTOPP_GET_FUNCTION_ENTRY(name) (Name::name(), &ThisClass::Get##name)
0515 #define CRYPTOPP_SET_FUNCTION_ENTRY(name) (Name::name(), &ThisClass::Set##name)
0516 #define CRYPTOPP_SET_FUNCTION_ENTRY2(name1, name2) (Name::name1(), Name::name2(), &ThisClass::Set##name1##And##name2)
0517
0518 NAMESPACE_END
0519
0520 #endif