Update README.md
[nemesis.git] / Platform / StringConverter.cpp
1 /*
2  Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
3
4  Governed by the TrueCrypt License 3.0 the full text of which is contained in
5  the file License.txt included in TrueCrypt binary and source code distribution
6  packages.
7 */
8
9 #ifdef __GNUC__
10 #       include <cxxabi.h>
11 #endif
12 #include <locale>
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 {
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
38         wstring StringConverter::FromNumber (double number)
39         {
40                 wstringstream s;
41                 s << number;
42                 return s.str();
43         }
44
45         wstring StringConverter::FromNumber (int32 number)
46         {
47                 wstringstream s;
48                 s << number;
49                 return s.str();
50         }
51
52         wstring StringConverter::FromNumber (uint32 number)
53         {
54                 wstringstream s;
55                 s << number;
56                 return s.str();
57         }
58
59         wstring StringConverter::FromNumber (int64 number)
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                         size_t cut1 = (rawName.find (".?A") != string::npos) ? 4 : string::npos;
95                         size_t cut2 = rawName.find ("@");
96                         size_t 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         }
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         }
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
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
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)
213         {
214                 try
215                 {
216                         mbstate_t mbState;
217                         Memory::Zero (&mbState, sizeof (mbState));
218                         const wchar_t *src = wstr.c_str();
219
220                         size_t size = wcsrtombs (nullptr, &src, 0, &mbState);
221                         if (size == (size_t) -1)
222                                 throw StringConversionFailed (SRC_POS, wstr);
223
224                         vector <char> buf (size + 1);
225                         Memory::Zero (&mbState, sizeof (mbState));
226
227                         if ((size = wcsrtombs (&buf[0], &src, buf.size(), &mbState)) == (size_t) -1)
228                                 throw StringConversionFailed (SRC_POS, wstr);
229
230                         str.clear();
231                         str.insert (0, &buf.front(), size);
232                         Memory::Erase (&buf.front(), buf.size());
233                 }
234                 catch (...)
235                 {
236                         if (!noThrow)
237                                 throw;
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         }
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         }
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 == (size_t) -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)) == (size_t) -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 page took 0.032311 seconds and 3 git commands to generate. Download a nemesis OSX (sierra+high sierra, tested/working) binary, with fuse-ext3 via e2fsprogs, at this link. application and installer are signed by screwjack, llc. must install fuse with macFUSE layer first.