monotone

monotone Mtn Source Tree

Root/cryptopp/algparam.h

1#ifndef CRYPTOPP_ALGPARAM_H
2#define CRYPTOPP_ALGPARAM_H
3
4#include "cryptlib.h"
5#include "smartptr.h"
6#include "secblock.h"
7
8NAMESPACE_BEGIN(CryptoPP)
9
10//! used to pass byte array input as part of a NameValuePairs object
11/*! the deepCopy option is used when the NameValuePairs object can't
12keep a copy of the data available */
13class ConstByteArrayParameter
14{
15public:
16ConstByteArrayParameter(const char *data = NULL, bool deepCopy = false)
17{
18Assign((const byte *)data, data ? strlen(data) : 0, deepCopy);
19}
20ConstByteArrayParameter(const byte *data, unsigned int size, bool deepCopy = false)
21{
22Assign(data, size, deepCopy);
23}
24template <class T> ConstByteArrayParameter(const T &string, bool deepCopy = false)
25{
26CRYPTOPP_COMPILE_ASSERT(sizeof(string[0])==1);
27Assign((const byte *)string.data(), string.size(), deepCopy);
28}
29
30void Assign(const byte *data, unsigned int size, bool deepCopy)
31{
32if (deepCopy)
33m_block.Assign(data, size);
34else
35{
36m_data = data;
37m_size = size;
38}
39m_deepCopy = deepCopy;
40}
41
42const byte *begin() const {return m_deepCopy ? m_block.begin() : m_data;}
43const byte *end() const {return m_deepCopy ? m_block.end() : m_data + m_size;}
44unsigned int size() const {return m_deepCopy ? m_block.size() : m_size;}
45
46private:
47bool m_deepCopy;
48const byte *m_data;
49unsigned int m_size;
50SecByteBlock m_block;
51};
52
53class ByteArrayParameter
54{
55public:
56ByteArrayParameter(byte *data = NULL, unsigned int size = 0)
57: m_data(data), m_size(size) {}
58ByteArrayParameter(SecByteBlock &block)
59: m_data(block.begin()), m_size(block.size()) {}
60
61byte *begin() const {return m_data;}
62byte *end() const {return m_data + m_size;}
63unsigned int size() const {return m_size;}
64
65private:
66byte *m_data;
67unsigned int m_size;
68};
69
70class CombinedNameValuePairs : public NameValuePairs
71{
72public:
73CombinedNameValuePairs(const NameValuePairs &pairs1, const NameValuePairs &pairs2)
74: m_pairs1(pairs1), m_pairs2(pairs2) {}
75
76bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
77{
78if (strcmp(name, "ValueNames") == 0)
79return m_pairs1.GetVoidValue(name, valueType, pValue) && m_pairs2.GetVoidValue(name, valueType, pValue);
80else
81return m_pairs1.GetVoidValue(name, valueType, pValue) || m_pairs2.GetVoidValue(name, valueType, pValue);
82}
83
84const NameValuePairs &m_pairs1, &m_pairs2;
85};
86
87template <class T, class BASE>
88class GetValueHelperClass
89{
90public:
91GetValueHelperClass(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst)
92: m_pObject(pObject), m_name(name), m_valueType(&valueType), m_pValue(pValue), m_found(false), m_getValueNames(false)
93{
94if (strcmp(m_name, "ValueNames") == 0)
95{
96m_found = m_getValueNames = true;
97NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(std::string), *m_valueType);
98if (searchFirst)
99searchFirst->GetVoidValue(m_name, valueType, pValue);
100if (typeid(T) != typeid(BASE))
101pObject->BASE::GetVoidValue(m_name, valueType, pValue);
102((*reinterpret_cast<std::string *>(m_pValue) += "ThisPointer:") += typeid(T).name()) += ';';
103}
104
105if (!m_found && strncmp(m_name, "ThisPointer:", 12) == 0 && strcmp(m_name+12, typeid(T).name()) == 0)
106{
107NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T *), *m_valueType);
108*reinterpret_cast<const T **>(pValue) = pObject;
109m_found = true;
110return;
111}
112
113if (!m_found && searchFirst)
114m_found = searchFirst->GetVoidValue(m_name, valueType, pValue);
115
116if (!m_found && typeid(T) != typeid(BASE))
117m_found = pObject->BASE::GetVoidValue(m_name, valueType, pValue);
118}
119
120operator bool() const {return m_found;}
121
122template <class R>
123GetValueHelperClass<T,BASE> & operator()(const char *name, const R & (T::*pm)() const)
124{
125if (m_getValueNames)
126(*reinterpret_cast<std::string *>(m_pValue) += name) += ";";
127if (!m_found && strcmp(name, m_name) == 0)
128{
129NameValuePairs::ThrowIfTypeMismatch(name, typeid(R), *m_valueType);
130*reinterpret_cast<R *>(m_pValue) = (m_pObject->*pm)();
131m_found = true;
132}
133return *this;
134}
135
136GetValueHelperClass<T,BASE> &Assignable()
137{
138if (m_getValueNames)
139((*reinterpret_cast<std::string *>(m_pValue) += "ThisObject:") += typeid(T).name()) += ';';
140if (!m_found && strncmp(m_name, "ThisObject:", 11) == 0 && strcmp(m_name+11, typeid(T).name()) == 0)
141{
142NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T), *m_valueType);
143*reinterpret_cast<T *>(m_pValue) = *m_pObject;
144m_found = true;
145}
146return *this;
147}
148
149private:
150const T *m_pObject;
151const char *m_name;
152const std::type_info *m_valueType;
153void *m_pValue;
154bool m_found, m_getValueNames;
155};
156
157template <class BASE, class T>
158GetValueHelperClass<T, BASE> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL, BASE *dummy=NULL)
159{
160return GetValueHelperClass<T, BASE>(pObject, name, valueType, pValue, searchFirst);
161}
162
163template <class T>
164GetValueHelperClass<T, T> GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL)
165{
166return GetValueHelperClass<T, T>(pObject, name, valueType, pValue, searchFirst);
167}
168
169// ********************************************************
170
171template <class R>
172R Hack_DefaultValueFromConstReferenceType(const R &)
173{
174return R();
175}
176
177template <class R>
178bool Hack_GetValueIntoConstReference(const NameValuePairs &source, const char *name, const R &value)
179{
180return source.GetValue(name, const_cast<R &>(value));
181}
182
183template <class T, class BASE>
184class AssignFromHelperClass
185{
186public:
187AssignFromHelperClass(T *pObject, const NameValuePairs &source)
188: m_pObject(pObject), m_source(source), m_done(false)
189{
190if (source.GetThisObject(*pObject))
191m_done = true;
192else if (typeid(BASE) != typeid(T))
193pObject->BASE::AssignFrom(source);
194}
195
196template <class R>
197AssignFromHelperClass & operator()(const char *name, void (T::*pm)(R))// VC60 workaround: "const R &" here causes compiler error
198{
199if (!m_done)
200{
201R value = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<R>(*(int *)NULL));
202if (!Hack_GetValueIntoConstReference(m_source, name, value))
203throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name + "'");
204(m_pObject->*pm)(value);
205}
206return *this;
207}
208
209template <class R, class S>
210AssignFromHelperClass & operator()(const char *name1, const char *name2, void (T::*pm)(R, S))// VC60 workaround: "const R &" here causes compiler error
211{
212if (!m_done)
213{
214R value1 = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<R>(*(int *)NULL));
215if (!Hack_GetValueIntoConstReference(m_source, name1, value1))
216throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name1 + "'");
217S value2 = Hack_DefaultValueFromConstReferenceType(reinterpret_cast<S>(*(int *)NULL));
218if (!Hack_GetValueIntoConstReference(m_source, name2, value2))
219throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name2 + "'");
220(m_pObject->*pm)(value1, value2);
221}
222return *this;
223}
224
225private:
226T *m_pObject;
227const NameValuePairs &m_source;
228bool m_done;
229};
230
231template <class BASE, class T>
232AssignFromHelperClass<T, BASE> AssignFromHelper(T *pObject, const NameValuePairs &source, BASE *dummy=NULL)
233{
234return AssignFromHelperClass<T, BASE>(pObject, source);
235}
236
237template <class T>
238AssignFromHelperClass<T, T> AssignFromHelper(T *pObject, const NameValuePairs &source)
239{
240return AssignFromHelperClass<T, T>(pObject, source);
241}
242
243// ********************************************************
244
245// This should allow the linker to discard Integer code if not needed.
246extern bool (*AssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt);
247
248const std::type_info & IntegerTypeId();
249
250template <class BASE, class T>
251class AlgorithmParameters : public NameValuePairs
252{
253public:
254AlgorithmParameters(const BASE &base, const char *name, const T &value)
255: m_base(base), m_name(name), m_value(value)
256#ifndef NDEBUG
257, m_used(false)
258#endif
259{}
260
261#ifndef NDEBUG
262AlgorithmParameters(const AlgorithmParameters &copy)
263: m_base(copy.m_base), m_name(copy.m_name), m_value(copy.m_value), m_used(false)
264{
265copy.m_used = true;
266}
267
268// TODO: revisit after implementing some tracing mechanism, this won't work because of exceptions
269//~AlgorithmParameters() {assert(m_used);}// use assert here because we don't want to throw out of a destructor
270#endif
271
272template <class R>
273AlgorithmParameters<AlgorithmParameters<BASE,T>, R> operator()(const char *name, const R &value) const
274{
275return AlgorithmParameters<AlgorithmParameters<BASE,T>, R>(*this, name, value);
276}
277
278bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
279{
280if (strcmp(name, "ValueNames") == 0)
281{
282ThrowIfTypeMismatch(name, typeid(std::string), valueType);
283m_base.GetVoidValue(name, valueType, pValue);
284(*reinterpret_cast<std::string *>(pValue) += m_name) += ";";
285return true;
286}
287else if (strcmp(name, m_name) == 0)
288{
289// special case for retrieving an Integer parameter when an int was passed in
290if (!(AssignIntToInteger != NULL && typeid(T) == typeid(int) && AssignIntToInteger(valueType, pValue, &m_value)))
291{
292ThrowIfTypeMismatch(name, typeid(T), valueType);
293*reinterpret_cast<T *>(pValue) = m_value;
294}
295#ifndef NDEBUG
296m_used = true;
297#endif
298return true;
299}
300else
301return m_base.GetVoidValue(name, valueType, pValue);
302}
303
304private:
305BASE m_base;
306const char *m_name;
307T m_value;
308#ifndef NDEBUG
309mutable bool m_used;
310#endif
311};
312
313template <class T>
314AlgorithmParameters<NullNameValuePairs,T> MakeParameters(const char *name, const T &value)
315{
316return AlgorithmParameters<NullNameValuePairs,T>(g_nullNameValuePairs, name, value);
317}
318
319#define CRYPTOPP_GET_FUNCTION_ENTRY(name)(Name::name(), &ThisClass::Get##name)
320#define CRYPTOPP_SET_FUNCTION_ENTRY(name)(Name::name(), &ThisClass::Set##name)
321#define CRYPTOPP_SET_FUNCTION_ENTRY2(name1, name2)(Name::name1(), Name::name2(), &ThisClass::Set##name1##And##name2)
322
323NAMESPACE_END
324
325#endif

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status