monotone

monotone Mtn Source Tree

Root/botan/parsing.cpp

1/*************************************************
2* Parser Functions Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/parsing.h>
7#include <botan/exceptn.h>
8#include <botan/charset.h>
9
10namespace Botan {
11
12/*************************************************
13* Convert a string into an integer *
14*************************************************/
15u32bit to_u32bit(const std::string& number)
16 {
17 u32bit n = 0;
18
19 for(std::string::const_iterator j = number.begin(); j != number.end(); j++)
20 {
21 const u32bit OVERFLOW_MARK = 0xFFFFFFFF / 10;
22
23 byte digit = char2digit(*j);
24
25 if((n > OVERFLOW_MARK) || (n == OVERFLOW_MARK && digit > 5))
26 throw Decoding_Error("to_u32bit: Integer overflow");
27 n *= 10;
28 n += digit;
29 }
30 return n;
31 }
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 = 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 = "";
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 elems.push_back(substr);
127 substr = "";
128 }
129 else
130 substr += *j;
131 }
132
133 if(substr == "")
134 throw Format_Error("Unable to split string: " + str);
135 elems.push_back(substr);
136
137 return elems;
138 }
139
140/*************************************************
141* Parse an ASN.1 OID string *
142*************************************************/
143std::vector<u32bit> parse_asn1_oid(const std::string& oid)
144 {
145 std::string substring;
146 std::vector<u32bit> oid_elems;
147
148 for(std::string::const_iterator j = oid.begin(); j != oid.end(); j++)
149 {
150 char c = *j;
151
152 if(c == '.')
153 {
154 if(substring == "")
155 throw Invalid_OID(oid);
156 oid_elems.push_back(to_u32bit(substring));
157 substring = "";
158 }
159 else
160 substring += c;
161 }
162
163 if(substring == "")
164 throw Invalid_OID(oid);
165 oid_elems.push_back(to_u32bit(substring));
166
167 if(oid_elems.size() < 2)
168 throw Invalid_OID(oid);
169
170 return oid_elems;
171 }
172
173/*************************************************
174* X.500 String Comparison *
175*************************************************/
176bool x500_name_cmp(const std::string& name1, const std::string& name2)
177 {
178 std::string::const_iterator p1 = name1.begin();
179 std::string::const_iterator p2 = name2.begin();
180
181 while((p1 != name1.end()) && is_space(*p1)) p1++;
182 while((p2 != name2.end()) && is_space(*p2)) p2++;
183
184 while(p1 != name1.end() && p2 != name2.end())
185 {
186 if(is_space(*p1))
187 {
188 if(!is_space(*p2))
189 return false;
190
191 while((p1 != name1.end()) && is_space(*p1)) p1++;
192 while((p2 != name2.end()) && is_space(*p2)) p2++;
193
194 if(p1 == name1.end() && p2 == name2.end())
195 return true;
196 }
197
198 if(to_lower(*p1) != to_lower(*p2))
199 return false;
200 p1++;
201 p2++;
202 }
203
204 while((p1 != name1.end()) && is_space(*p1)) p1++;
205 while((p2 != name2.end()) && is_space(*p2)) p2++;
206
207 if((p1 != name1.end()) || (p2 != name2.end()))
208 return false;
209 return true;
210 }
211
212/*************************************************
213* Convert from UTF-8 to ISO 8859-1 *
214*************************************************/
215std::string utf2iso(const std::string& utf8)
216 {
217 std::string iso8859;
218
219 u32bit position = 0;
220 while(position != utf8.size())
221 {
222 const byte c1 = (byte)utf8[position++];
223
224 if(c1 <= 0x7F)
225 iso8859 += (char)c1;
226 else if(c1 >= 0xC0 && c1 <= 0xC7)
227 {
228 if(position == utf8.size())
229 throw Decoding_Error("UTF-8: sequence truncated");
230
231 const byte c2 = (byte)utf8[position++];
232 const byte iso_char = ((c1 & 0x07) << 6) | (c2 & 0x3F);
233
234 if(iso_char <= 0x7F)
235 throw Decoding_Error("UTF-8: sequence longer than needed");
236
237 iso8859 += (char)iso_char;
238 }
239 else
240 throw Decoding_Error("UTF-8: Unicode chars not in Latin1 used");
241 }
242
243 return iso8859;
244 }
245
246/*************************************************
247* Convert from ISO 8859-1 to UTF-8 *
248*************************************************/
249std::string iso2utf(const std::string& iso8859)
250 {
251 std::string utf8;
252 for(u32bit j = 0; j != iso8859.size(); j++)
253 {
254 const byte c = (byte)iso8859[j];
255
256 if(c <= 0x7F)
257 utf8 += (char)c;
258 else
259 {
260 utf8 += (char)(0xC0 | (c >> 6));
261 utf8 += (char)(0x80 | (c & 0x3F));
262 }
263 }
264 return utf8;
265 }
266
267/*************************************************
268* Parse and compute an arithmetic expression *
269*************************************************/
270u32bit parse_expr(const std::string& expr)
271 {
272 const bool have_add = (expr.find('+') != std::string::npos);
273 const bool have_mul = (expr.find('*') != std::string::npos);
274
275 if(have_add)
276 {
277 std::vector<std::string> sub_expr = split_on(expr, '+');
278 u32bit result = 0;
279 for(u32bit j = 0; j != sub_expr.size(); j++)
280 result += parse_expr(sub_expr[j]);
281 return result;
282 }
283 else if(have_mul)
284 {
285 std::vector<std::string> sub_expr = split_on(expr, '*');
286 u32bit result = 1;
287 for(u32bit j = 0; j != sub_expr.size(); j++)
288 result *= parse_expr(sub_expr[j]);
289 return result;
290 }
291 else
292 return to_u32bit(expr);
293 }
294
295}

Archive Download this file

Branches

Tags

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