Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

scan_name.cpp
Go to the documentation of this file.
1 /*
2 * SCAN Name Abstraction
3 * (C) 2008-2009,2015 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/scan_name.h>
9 #include <botan/parsing.h>
10 #include <botan/exceptn.h>
11
12 namespace Botan {
13
14 namespace {
15
16 std::string make_arg(
17 const std::vector<std::pair<size_t, std::string> >& name, size_t start)
18 {
19 std::string output = name[start].second;
20 size_t level = name[start].first;
21
22 size_t paren_depth = 0;
23
24 for(size_t i = start + 1; i != name.size(); ++i)
25 {
26 if(name[i].first <= name[start].first)
27 break;
28
29 if(name[i].first > level)
30 {
31 output += "(" + name[i].second;
32 ++paren_depth;
33 }
34 else if(name[i].first < level)
35 {
36 output += ")," + name[i].second;
37 --paren_depth;
38 }
39 else
40 {
41 if(output[output.size() - 1] != '(')
42 output += ",";
43 output += name[i].second;
44 }
45
46 level = name[i].first;
47 }
48
49 for(size_t i = 0; i != paren_depth; ++i)
50 output += ")";
51
52 return output;
53 }
54
55 }
56
57 SCAN_Name::SCAN_Name(const char* algo_spec) : SCAN_Name(std::string(algo_spec))
58 {
59 }
60
61 SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg_name(), m_args(), m_mode_info()
62 {
63 std::vector<std::pair<size_t, std::string> > name;
64 size_t level = 0;
65 std::pair<size_t, std::string> accum = std::make_pair(level, "");
66
67 const std::string decoding_error = "Bad SCAN name '" + algo_spec + "': ";
68
69 for(size_t i = 0; i != algo_spec.size(); ++i)
70 {
71 char c = algo_spec[i];
72
73 if(c == '/' || c == ',' || c == '(' || c == ')')
74 {
75 if(c == '(')
76 ++level;
77 else if(c == ')')
78 {
79 if(level == 0)
80 throw Decoding_Error(decoding_error + "Mismatched parens");
81 --level;
82 }
83
84 if(c == '/' && level > 0)
85 accum.second.push_back(c);
86 else
87 {
88 if(accum.second != "")
89 name.push_back(accum);
90 accum = std::make_pair(level, "");
91 }
92 }
93 else
94 accum.second.push_back(c);
95 }
96
97 if(accum.second != "")
98 name.push_back(accum);
99
100 if(level != 0)
101 throw Decoding_Error(decoding_error + "Missing close paren");
102
103 if(name.size() == 0)
104 throw Decoding_Error(decoding_error + "Empty name");
105
106 m_alg_name = name[0].second;
107
108 bool in_modes = false;
109
110 for(size_t i = 1; i != name.size(); ++i)
111 {
112 if(name[i].first == 0)
113 {
114 m_mode_info.push_back(make_arg(name, i));
115 in_modes = true;
116 }
117 else if(name[i].first == 1 && !in_modes)
118 m_args.push_back(make_arg(name, i));
119 }
120 }
121
122 std::string SCAN_Name::arg(size_t i) const
123 {
124 if(i >= arg_count())
125 throw Invalid_Argument("SCAN_Name::arg " + std::to_string(i) +
126 " out of range for '" + as_string() + "'");
127 return m_args[i];
128 }
129
130 std::string SCAN_Name::arg(size_t i, const std::string& def_value) const
131 {
132 if(i >= arg_count())
133 return def_value;
134 return m_args[i];
135 }
136
137 size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const
138 {
139 if(i >= arg_count())
140 return def_value;
141 return to_u32bit(m_args[i]);
142 }
143
144 }
Botan::to_u32bit
uint32_t to_u32bit(const std::string &str)
Definition: parsing.cpp:18
Botan::SCAN_Name::arg
std::string arg(size_t i) const
Definition: scan_name.cpp:122
Botan::Invalid_Argument
Definition: exceptn.h:34
std
Definition: bigint.h:619
Botan::SCAN_Name::arg_count
size_t arg_count() const
Definition: scan_name.h:50
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
Botan::SCAN_Name::as_string
const std::string & as_string() const
Definition: scan_name.h:40
Botan::SCAN_Name::arg_as_integer
size_t arg_as_integer(size_t i, size_t def_value) const
Definition: scan_name.cpp:137
Botan::Decoding_Error
Definition: exceptn.h:189
Botan
Definition: alg_id.cpp:13
Botan::SCAN_Name
Definition: scan_name.h:22
Botan::SCAN_Name::SCAN_Name
SCAN_Name(const char *algo_spec)
Definition: scan_name.cpp:57