monotone

monotone Mtn Source Tree

Root/botan/parsing.cpp

1/*************************************************
2* Parser Functions Source File *
3* (C) 1999-2007 The Botan Project *
4*************************************************/
5
6#include <botan/parsing.h>
7#include <botan/exceptn.h>
8#include <botan/charset.h>
9#include <botan/loadstor.h>
10
11namespace Botan {
12
13/*************************************************
14* Convert a string into an integer *
15*************************************************/
16u32bit to_u32bit(const std::string& number)
17 {
18 u32bit n = 0;
19
20 for(std::string::const_iterator j = number.begin(); j != number.end(); ++j)
21 {
22 const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10;
23
24 byte digit = Charset::char2digit(*j);
25
26 if((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5))
27 throw Decoding_Error("to_u32bit: Integer overflow");
28 n *= 10;
29 n += digit;
30 }
31 return n;
32 }
33
34/*************************************************
35* Convert an integer into a string *
36*************************************************/
37std::string to_string(u64bit n, u32bit min_len)
38 {
39 std::string lenstr;
40 if(n)
41 {
42 while(n > 0)
43 {
44 lenstr = Charset::digit2char(n % 10) + lenstr;
45 n /= 10;
46 }
47 }
48 else
49 lenstr = "0";
50
51 while(lenstr.size() < min_len)
52 lenstr = "0" + lenstr;
53
54 return lenstr;
55 }
56
57/*************************************************
58* Parse a SCAN-style algorithm name *
59*************************************************/
60std::vector<std::string> parse_algorithm_name(const std::string& namex)
61 {
62 if(namex.find('(') == std::string::npos &&
63 namex.find(')') == std::string::npos)
64 return std::vector<std::string>(1, namex);
65
66 std::string name = namex, substring;
67 std::vector<std::string> elems;
68 u32bit level = 0;
69
70 elems.push_back(name.substr(0, name.find('(')));
71 name = name.substr(name.find('('));
72
73 for(std::string::const_iterator j = name.begin(); j != name.end(); ++j)
74 {
75 char c = *j;
76
77 if(c == '(')
78 ++level;
79 if(c == ')')
80 {
81 if(level == 1 && j == name.end() - 1)
82 {
83 if(elems.size() == 1)
84 elems.push_back(substring.substr(1));
85 else
86 elems.push_back(substring);
87 return elems;
88 }
89
90 if(level == 0 || (level == 1 && j != name.end() - 1))
91 throw Invalid_Algorithm_Name(namex);
92 --level;
93 }
94
95 if(c == ',' && level == 1)
96 {
97 if(elems.size() == 1)
98 elems.push_back(substring.substr(1));
99 else
100 elems.push_back(substring);
101 substring.clear();
102 }
103 else
104 substring += c;
105 }
106
107 if(substring != "")
108 throw Invalid_Algorithm_Name(namex);
109
110 return elems;
111 }
112
113/*************************************************
114* Split the string on slashes *
115*************************************************/
116std::vector<std::string> split_on(const std::string& str, char delim)
117 {
118 std::vector<std::string> elems;
119 if(str == "") return elems;
120
121 std::string substr;
122 for(std::string::const_iterator j = str.begin(); j != str.end(); ++j)
123 {
124 if(*j == delim)
125 {
126 if(substr != "")
127 elems.push_back(substr);
128 substr.clear();
129 }
130 else
131 substr += *j;
132 }
133
134 if(substr == "")
135 throw Format_Error("Unable to split string: " + str);
136 elems.push_back(substr);
137
138 return elems;
139 }
140
141/*************************************************
142* Parse an ASN.1 OID string *
143*************************************************/
144std::vector<u32bit> parse_asn1_oid(const std::string& oid)
145 {
146 std::string substring;
147 std::vector<u32bit> oid_elems;
148
149 for(std::string::const_iterator j = oid.begin(); j != oid.end(); ++j)
150 {
151 char c = *j;
152
153 if(c == '.')
154 {
155 if(substring == "")
156 throw Invalid_OID(oid);
157 oid_elems.push_back(to_u32bit(substring));
158 substring.clear();
159 }
160 else
161 substring += c;
162 }
163
164 if(substring == "")
165 throw Invalid_OID(oid);
166 oid_elems.push_back(to_u32bit(substring));
167
168 if(oid_elems.size() < 2)
169 throw Invalid_OID(oid);
170
171 return oid_elems;
172 }
173
174/*************************************************
175* X.500 String Comparison *
176*************************************************/
177bool x500_name_cmp(const std::string& name1, const std::string& name2)
178 {
179 std::string::const_iterator p1 = name1.begin();
180 std::string::const_iterator p2 = name2.begin();
181
182 while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
183 while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;
184
185 while(p1 != name1.end() && p2 != name2.end())
186 {
187 if(Charset::is_space(*p1))
188 {
189 if(!Charset::is_space(*p2))
190 return false;
191
192 while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
193 while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;
194
195 if(p1 == name1.end() && p2 == name2.end())
196 return true;
197 }
198
199 if(!Charset::caseless_cmp(*p1, *p2))
200 return false;
201 ++p1;
202 ++p2;
203 }
204
205 while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1;
206 while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2;
207
208 if((p1 != name1.end()) || (p2 != name2.end()))
209 return false;
210 return true;
211 }
212
213/*************************************************
214* Parse and compute an arithmetic expression *
215*************************************************/
216u32bit parse_expr(const std::string& expr)
217 {
218 const bool have_add = (expr.find('+') != std::string::npos);
219 const bool have_mul = (expr.find('*') != std::string::npos);
220
221 if(have_add)
222 {
223 std::vector<std::string> sub_expr = split_on(expr, '+');
224 u32bit result = 0;
225 for(u32bit j = 0; j != sub_expr.size(); ++j)
226 result += parse_expr(sub_expr[j]);
227 return result;
228 }
229 else if(have_mul)
230 {
231 std::vector<std::string> sub_expr = split_on(expr, '*');
232 u32bit result = 1;
233 for(u32bit j = 0; j != sub_expr.size(); ++j)
234 result *= parse_expr(sub_expr[j]);
235 return result;
236 }
237 else
238 return to_u32bit(expr);
239 }
240
241/*************************************************
242* Convert a decimal-dotted string to binary IP *
243*************************************************/
244u32bit string_to_ipv4(const std::string& str)
245 {
246 std::vector<std::string> parts = split_on(str, '.');
247
248 if(parts.size() != 4)
249 throw Decoding_Error("Invalid IP string " + str);
250
251 u32bit ip = 0;
252
253 for(size_t j = 0; j != parts.size(); j++)
254 {
255 u32bit octet = to_u32bit(parts[j]);
256
257 if(octet > 255)
258 throw Decoding_Error("Invalid IP string " + str);
259
260 ip = (ip << 8) | (octet & 0xFF);
261 }
262
263 return ip;
264 }
265
266/*************************************************
267* Convert an IP address to decimal-dotted string *
268*************************************************/
269std::string ipv4_to_string(u32bit ip)
270 {
271 std::string str;
272
273 for(size_t j = 0; j != sizeof(ip); j++)
274 {
275 if(j)
276 str += ".";
277 str += to_string(get_byte(j, ip));
278 }
279
280 return str;
281 }
282
283}

Archive Download this file

Branches

Tags

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