|
|
1.1 root 1: /*
2: Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
3:
4: Governed by the TrueCrypt License 2.4 the full text of which is contained
5: in the file License.txt included in TrueCrypt binary and source code
6: distribution packages.
7: */
8:
9: #ifdef __GNUC__
10: # include <cxxabi.h>
11: #endif
12: #include <typeinfo>
13: #include "Buffer.h"
14: #include "Exception.h"
15: #include "ForEach.h"
16: #include "StringConverter.h"
17: #include "SystemException.h"
18:
19: namespace TrueCrypt
20: {
21: wstring StringConverter::FromNumber (double number)
22: {
23: wstringstream s;
24: s << number;
25: return s.str();
26: }
27:
28: wstring StringConverter::FromNumber (unsigned int number)
29: {
30: wstringstream s;
31: s << number;
32: return s.str();
33: }
34:
35: wstring StringConverter::FromNumber (int64 number)
36: {
37: wstringstream s;
38: s << number;
39: return s.str();
40: }
41:
42: wstring StringConverter::FromNumber (int number)
43: {
44: wstringstream s;
45: s << number;
46: return s.str();
47: }
48:
49: wstring StringConverter::FromNumber (long number)
50: {
51: wstringstream s;
52: s << number;
53: return s.str();
54: }
55:
56: wstring StringConverter::FromNumber (unsigned long number)
57: {
58: wstringstream s;
59: s << number;
60: return s.str();
61: }
62:
63: wstring StringConverter::FromNumber (uint64 number)
64: {
65: wstringstream s;
66: s << number;
67: return s.str();
68: }
69:
70: string StringConverter::GetTrailingNumber (const string &str)
71: {
72: size_t start = str.find_last_not_of ("0123456789");
73: if (start == string::npos)
74: return str;
75:
76: string s = str.substr (start + 1);
77: if (s.empty ())
78: throw ParameterIncorrect (SRC_POS);
79:
80: return s;
81: }
82:
83: string StringConverter::GetTypeName (const type_info &typeInfo)
84: {
85: try
86: {
87: #ifdef _MSC_VER
88: // type_info::name() leaks memory as of MS VC++ 8.0
89: string rawName (typeInfo.raw_name());
90:
91: int cut1 = (rawName.find (".?A") != string::npos) ? 4 : string::npos;
92: int cut2 = rawName.find ("@");
93: int cut3 = rawName.find ("@@");
94:
95: if (cut1 == string::npos || cut2 == string::npos || cut3 == string::npos)
96: return typeInfo.name();
97:
98: return rawName.substr (cut2 + 1, cut3 - cut2 - 1) + "::" + rawName.substr (cut1, cut2 - cut1);
99:
100: #elif defined (__GNUC__)
101: int status;
102: char *name = abi::__cxa_demangle (typeInfo.name(), nullptr, nullptr, &status);
103:
104: if (name)
105: {
106: string s (name);
107: free (name);
108: return s;
109: }
110: #endif
111: }
112: catch (...) { }
113:
114: return typeInfo.name();
115: }
116:
117: wstring StringConverter::QuoteSpaces (const wstring &str)
118: {
119: if (str.find (L' ') == string::npos)
120: return str;
121:
122: wstring escaped (L"'");
123: foreach (wchar_t c, str)
124: {
125: if (c == L'\'')
126: escaped += L'\'';
127: escaped += c;
128: }
129: return escaped + L'\'';
130: }
131:
132: vector <string> StringConverter::Split (const string &str, const string &separators, bool returnEmptyFields)
133: {
134: vector <string> elements;
135:
136: if (!returnEmptyFields)
137: {
138: size_t p = 0;
139: while ((p = str.find_first_not_of (separators, p)) != string::npos)
140: {
141: size_t end = str.find_first_of (separators, p);
142: if (end == string::npos)
143: {
144: elements.push_back (str.substr (p));
145: break;
146: }
147:
148: elements.push_back (str.substr (p, end - p));
149: p = end;
150: }
151: }
152: else
153: {
154: string element;
155: elements.push_back (element);
156: foreach (char c, str)
157: {
158: if (separators.find (c) != string::npos)
159: {
160: element.erase();
161: elements.push_back (element);
162: }
163: else
164: {
165: elements.back() += c;
166: }
167: }
168: }
169:
170: return elements;
171: }
172:
173: wstring StringConverter::ToExceptionString (const exception &ex)
174: {
175: const SystemException *sysEx = dynamic_cast <const SystemException *> (&ex);
176: if (sysEx)
177: return ToWide (sysEx->what()) + L": " + sysEx->SystemText() + L": " + sysEx->GetSubject();
178:
179: if (ex.what() && !string (ex.what()).empty())
180: return ToWide (GetTypeName (typeid (ex)) + ": " + ex.what());
181:
182: return ToWide (GetTypeName (typeid (ex)));
183: }
184:
185: string StringConverter::ToSingle (const wstring &str, bool noThrow)
186: {
187: try
188: {
189: mbstate_t mbState;
190: Memory::Zero (&mbState, sizeof (mbState));
191: const wchar_t *src = str.c_str();
192:
193: size_t size = wcsrtombs (nullptr, &src, 0, &mbState);
194: if (size == -1)
195: throw StringConversionFailed (SRC_POS, str);
196:
197: vector <char> buf (size + 1);
198: Memory::Zero (&mbState, sizeof (mbState));
199:
200: if ((size = wcsrtombs (&buf[0], &src, buf.size(), &mbState)) == -1)
201: throw StringConversionFailed (SRC_POS, str);
202:
203: string s;
204: s.insert (s.begin(), buf.begin(), buf.begin() + size);
205: return s;
206: }
207: catch (...)
208: {
209: if (noThrow)
210: return "";
211: throw;
212: }
213: }
214:
215: uint32 StringConverter::ToUInt32 (const string &str)
216: {
217: uint32 n;
218: stringstream ss (str);
219:
220: ss >> n;
221: if (ss.fail() || n == 0xffffFFFFU)
222: throw ParameterIncorrect (SRC_POS);
223:
224: return n;
225: }
226:
227: uint32 StringConverter::ToUInt32 (const wstring &str)
228: {
229: uint32 n;
230: wstringstream ss (str);
231:
232: ss >> n;
233: if (ss.fail() || n == 0xffffFFFFU)
234: throw ParameterIncorrect (SRC_POS);
235:
236: return n;
237: }
238:
239: uint64 StringConverter::ToUInt64 (const string &str)
240: {
241: uint64 n;
242: stringstream ss (str);
243:
244: ss >> n;
245: if (ss.fail() || n == 0xffffFFFFffffFFFFULL)
246: throw ParameterIncorrect (SRC_POS);
247:
248: return n;
249: }
250:
251: uint64 StringConverter::ToUInt64 (const wstring &str)
252: {
253: uint64 n;
254: wstringstream ss (str);
255:
256: ss >> n;
257: if (ss.fail() || n == 0xffffFFFFffffFFFFULL)
258: throw ParameterIncorrect (SRC_POS);
259:
260: return n;
261: }
262:
263: wstring StringConverter::ToWide (const string &str, bool noThrow)
264: {
265: try
266: {
267: mbstate_t mbState;
268: Memory::Zero (&mbState, sizeof (mbState));
269: const char *src = str.c_str();
270:
271: size_t size = mbsrtowcs (nullptr, &src, 0, &mbState);
272: if (size == -1)
273: throw StringConversionFailed (SRC_POS);
274:
275: vector <wchar_t> buf (size + 1);
276: Memory::Zero (&mbState, sizeof (mbState));
277:
278: if ((size = mbsrtowcs (&buf[0], &src, buf.size(), &mbState)) == -1)
279: throw StringConversionFailed (SRC_POS);
280:
281: wstring s;
282: s.insert (s.begin(), buf.begin(), buf.begin() + size);
283: return s;
284: }
285: catch (...)
286: {
287: if (noThrow)
288: return L"";
289: throw;
290: }
291: }
292:
293: void StringConverter::ToWideBuffer (const wstring &str, wchar_t *buffer, size_t bufferSize)
294: {
295: if (str.length() < 1)
296: {
297: buffer[0] = 0;
298: return;
299: }
300:
301: BufferPtr (
302: (byte *) buffer,
303: bufferSize).CopyFrom (
304: ConstBufferPtr ((byte *) (wstring (str).c_str()),
305: (str.length() + 1) * sizeof (wchar_t)
306: )
307: );
308: }
309:
310: string StringConverter::Trim (const string &str)
311: {
312: size_t start = 0;
313: size_t end = str.size();
314: if (end < 1)
315: return str;
316:
317: foreach (char c, str)
318: {
319: if (c > ' ')
320: break;
321: ++start;
322: }
323:
324: foreach_reverse (char c, str)
325: {
326: if (c > ' ')
327: break;
328: --end;
329: }
330:
331: return str.substr (start, end - start);
332: }
333: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.