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