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