Botan 2.13.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(const std::vector<std::pair<size_t, std::string>>& name, size_t start)
17 {
18 std::string output = name[start].second;
19 size_t level = name[start].first;
20
21 size_t paren_depth = 0;
22
23 for(size_t i = start + 1; i != name.size(); ++i)
24 {
25 if(name[i].first <= name[start].first)
26 break;
27
28 if(name[i].first > level)
29 {
30 output += "(" + name[i].second;
31 ++paren_depth;
32 }
33 else if(name[i].first < level)
34 {
35 output += ")," + name[i].second;
36 --paren_depth;
37 }
38 else
39 {
40 if(output[output.size() - 1] != '(')
41 output += ",";
42 output += name[i].second;
43 }
44
45 level = name[i].first;
46 }
47
48 for(size_t i = 0; i != paren_depth; ++i)
49 output += ")";
50
51 return output;
52 }
53
54 }
55
56 SCAN_Name::SCAN_Name(const char* algo_spec) : SCAN_Name(std::string(algo_spec))
57 {
58 }
59
60 SCAN_Name::SCAN_Name(std::string algo_spec) : m_orig_algo_spec(algo_spec), m_alg_name(), m_args(), m_mode_info()
61 {
62 if(algo_spec.size() == 0)
63 throw Invalid_Argument("Expected algorithm name, got empty string");
64
65 std::vector<std::pair<size_t, std::string>> name;
66 size_t level = 0;
67 std::pair<size_t, std::string> accum = std::make_pair(level, "");
68
69 const std::string decoding_error = "Bad SCAN name '" + algo_spec + "': ";
70
71 for(size_t i = 0; i != algo_spec.size(); ++i)
72 {
73 char c = algo_spec[i];
74
75 if(c == '/' || c == ',' || c == '(' || c == ')')
76 {
77 if(c == '(')
78 ++level;
79 else if(c == ')')
80 {
81 if(level == 0)
82 throw Decoding_Error(decoding_error + "Mismatched parens");
83 --level;
84 }
85
86 if(c == '/' && level > 0)
87 accum.second.push_back(c);
88 else
89 {
90 if(accum.second != "")
91 name.push_back(accum);
92 accum = std::make_pair(level, "");
93 }
94 }
95 else
96 accum.second.push_back(c);
97 }
98
99 if(accum.second != "")
100 name.push_back(accum);
101
102 if(level != 0)
103 throw Decoding_Error(decoding_error + "Missing close paren");
104
105 if(name.size() == 0)
106 throw Decoding_Error(decoding_error + "Empty name");
107
108 m_alg_name = name[0].second;
109
110 bool in_modes = false;
111
112 for(size_t i = 1; i != name.size(); ++i)
113 {
114 if(name[i].first == 0)
115 {
116 m_mode_info.push_back(make_arg(name, i));
117 in_modes = true;
118 }
119 else if(name[i].first == 1 && !in_modes)
120 m_args.push_back(make_arg(name, i));
121 }
122 }
123
124 std::string SCAN_Name::arg(size_t i) const
125 {
126 if(i >= arg_count())
127 throw Invalid_Argument("SCAN_Name::arg " + std::to_string(i) +
128 " out of range for '" + to_string() + "'");
129 return m_args[i];
130 }
131
132 std::string SCAN_Name::arg(size_t i, const std::string& def_value) const
133 {
134 if(i >= arg_count())
135 return def_value;
136 return m_args[i];
137 }
138
139 size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const
140 {
141 if(i >= arg_count())
142 return def_value;
143 return to_u32bit(m_args[i]);
144 }
145
146 }
Botan::SCAN_Name::arg
std::string arg(size_t i) const
Definition: scan_name.cpp:124
Botan::Invalid_Argument
Definition: exceptn.h:136
std
Definition: bigint.h:1135
Botan::SCAN_Name::arg_count
size_t arg_count() const
Definition: scan_name.h:56
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
Botan::to_u32bit
uint32_t to_u32bit(const std::string &str)
Definition: parsing.cpp:35
Botan::Decoding_Error
Definition: exceptn.h:199
name
std::string name
Definition: commoncrypto_hash.cpp:23
Botan::SCAN_Name::arg_as_integer
size_t arg_as_integer(size_t i, size_t def_value) const
Definition: scan_name.cpp:139
Botan
Definition: alg_id.cpp:13
Botan::SCAN_Name
Definition: scan_name.h:23
Botan::SCAN_Name::to_string
const std::string & to_string() const
Definition: scan_name.h:41
Botan::SCAN_Name::SCAN_Name
SCAN_Name(const char *algo_spec)
Definition: scan_name.cpp:56