|
1 /* |
|
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #pragma warning (disable: 4786) |
|
20 |
|
21 #include "stringutils.h" |
|
22 |
|
23 // System includes |
|
24 #include <iostream> |
|
25 #include <algorithm> |
|
26 #include <string> |
|
27 #include <sstream> |
|
28 |
|
29 // User includes |
|
30 #include "is_utils.h" |
|
31 #include "logger.h" |
|
32 #include "utility_interface.h" |
|
33 |
|
34 // Constants |
|
35 const int KInterpretSISExpectedSIDLength = 8; |
|
36 const int KInterpretSISCtlIndexLength = 4; |
|
37 const std::string KStringUtilsWhiteSpace = "\t \r\n"; |
|
38 |
|
39 /** |
|
40 * Returns the size of the first occurance of an invalid directory separator. |
|
41 * @param aPath Path to be validated. |
|
42 * @param aIndex index from which the search begin. On function return this |
|
43 * index will point to the illegal directory separator. |
|
44 * @return 0 if path is valid. Else the number of character to be replaced. |
|
45 * e.g. /sys/bin/ should be replaced with \sys\bin\ |
|
46 * and \\sys\\bin\\ should be replaced with \sys\bin\ |
|
47 */ |
|
48 int StringUtils::FirstInvalidDirSeparatorSize(std::wstring& aPath, std::wstring::size_type& aIndex) |
|
49 { |
|
50 // If path semantics is correct (as needed by sisx library) |
|
51 // then the function will return 0 |
|
52 int ret = 0; |
|
53 int pos = 0; |
|
54 if((pos = aPath.find(L"/", aIndex)) != std::wstring::npos) |
|
55 { |
|
56 ret = 1; |
|
57 } |
|
58 else if((pos = aPath.find(L"\\\\", aIndex)) != std::wstring::npos) |
|
59 { |
|
60 ret = 2; |
|
61 } |
|
62 aIndex = pos; |
|
63 return ret; |
|
64 } |
|
65 |
|
66 std::wstring StringUtils::FixPathDelimiters( const std::string& aString ) |
|
67 { |
|
68 std::wstring ret = L""; |
|
69 char src[2048]; |
|
70 strcpy(src, aString.c_str()); |
|
71 // |
|
72 wchar_t* buf = NULL ; |
|
73 int len = ConvertMultiByteToWideChar(src, -1, NULL, 0); |
|
74 buf = new wchar_t[len+1]; |
|
75 len = ConvertMultiByteToWideChar(src, -1, buf, len); |
|
76 ret = std::wstring( buf ); |
|
77 delete[] buf; |
|
78 // |
|
79 std::wstring::size_type idx = 0; |
|
80 while(len = FirstInvalidDirSeparatorSize(ret, idx)) |
|
81 { |
|
82 ret.replace(idx, len, KDirectorySeparator); |
|
83 } |
|
84 // |
|
85 return ret; |
|
86 } |
|
87 |
|
88 |
|
89 std::string StringUtils::TrimWhiteSpace( const std::string& aString ) |
|
90 { |
|
91 const int start = aString.find_first_not_of( KStringUtilsWhiteSpace ); |
|
92 if (start == std::string::npos) |
|
93 { |
|
94 return ""; |
|
95 } |
|
96 // |
|
97 return aString.substr(start, 1 + aString.find_last_not_of( KStringUtilsWhiteSpace ) - start); |
|
98 } |
|
99 |
|
100 |
|
101 bool StringUtils::CheckForMatch( const std::string& aSearchFor, std::string& aLine ) |
|
102 { |
|
103 bool found = false; |
|
104 // |
|
105 if ( aLine.size() >= aSearchFor.size() ) |
|
106 { |
|
107 std::string prefix = aLine.substr( 0, aSearchFor.size() ); |
|
108 if ( prefix == aSearchFor ) |
|
109 { |
|
110 found = true; |
|
111 aLine = aLine.substr( aSearchFor.size() ); |
|
112 } |
|
113 } |
|
114 // |
|
115 return found; |
|
116 } |
|
117 |
|
118 |
|
119 std::string StringUtils::ToUpper( const std::string& aString ) |
|
120 { |
|
121 std::string ret( aString ); |
|
122 // |
|
123 std::transform( ret.begin(), ret.end(), ret.begin(), toupper ); |
|
124 // |
|
125 return ret; |
|
126 } |
|
127 |
|
128 std::wstring StringUtils::ToUpper( const std::wstring& aString ) |
|
129 { |
|
130 std::wstring ret( aString ); |
|
131 // |
|
132 std::transform( ret.begin(), ret.end(), ret.begin(), toupper ); |
|
133 // |
|
134 return ret; |
|
135 } |
|
136 |
|
137 |
|
138 std::string StringUtils::ToLower( const std::string& aString ) |
|
139 { |
|
140 std::string ret( aString ); |
|
141 // |
|
142 std::transform( ret.begin(), ret.end(), ret.begin(), tolower ); |
|
143 // |
|
144 return ret; |
|
145 } |
|
146 |
|
147 bool StringUtils::IsLastCharacter( const std::wstring& aString, wchar_t aChar ) |
|
148 { |
|
149 bool isLast = false; |
|
150 // |
|
151 if ( aString.length() ) |
|
152 { |
|
153 const wchar_t lastChar = aString[ aString.length() - 1 ]; |
|
154 isLast = ( lastChar == aChar ); |
|
155 } |
|
156 // |
|
157 return isLast; |
|
158 } |
|
159 |
|
160 |
|
161 bool StringUtils::StartsWithDrive( const std::wstring& aText ) |
|
162 { |
|
163 bool startsWithDrive = false; |
|
164 // |
|
165 if ( aText.length() >= 3 ) |
|
166 { |
|
167 const std::string prefix = ToUpper( Ucs2ToUtf8( aText.substr( 0, 3 ) ) ); |
|
168 // |
|
169 const char drive = prefix[ 0 ]; |
|
170 const char colon = prefix[ 1 ]; |
|
171 const char backslash = prefix[ 2 ]; |
|
172 // |
|
173 if ( colon == ':' && backslash == '\\' ) |
|
174 { |
|
175 startsWithDrive = ( drive >= 'A' && drive <= 'Z' ) || (drive == '!') ; |
|
176 } |
|
177 } |
|
178 // |
|
179 return startsWithDrive; |
|
180 } |
|
181 |
|
182 |
|
183 std::wstring StringUtils::MakePathFromSID( const std::wstring& aBasePath, TUint32 aSID ) |
|
184 { |
|
185 // Must make sure that the directory is eight characters long |
|
186 // since other parts of the code assume this (or check for it). |
|
187 std::wstringstream stream; |
|
188 stream << std::hex << aSID; |
|
189 // |
|
190 std::wstring ret = stream.str(); |
|
191 // |
|
192 while( ret.length() < KInterpretSISExpectedSIDLength ) |
|
193 { |
|
194 ret.insert( 0, L"0" ); |
|
195 } |
|
196 // Add trailing slash |
|
197 ret.append( L"\\" ); |
|
198 // |
|
199 // Convert it to a local path |
|
200 ConvertToLocalPath( ret, aBasePath ); |
|
201 return ret; |
|
202 } |
|
203 |
|
204 |
|
205 std::wstring StringUtils::BuildSisRegistryFileName( const int aIndex ) |
|
206 { |
|
207 std::wstringstream stream; |
|
208 stream << std::hex << aIndex; |
|
209 |
|
210 std::wstring ret = stream.str(); |
|
211 |
|
212 while( ret.length() < KInterpretSISExpectedSIDLength ) |
|
213 { |
|
214 ret.insert( 0, L"0" ); |
|
215 } |
|
216 |
|
217 ret.append( L".reg" ); |
|
218 |
|
219 return ret; |
|
220 } |
|
221 |
|
222 |
|
223 std::wstring StringUtils::BuildControllerFileName( const int aIndex, const int aCtlIndex) |
|
224 { |
|
225 std::wstringstream stream, stream2; |
|
226 stream << std::hex << aIndex; |
|
227 stream2 << std::hex << aCtlIndex; |
|
228 |
|
229 std::wstring ret = stream.str(); |
|
230 std::wstring ret2 = stream2.str(); |
|
231 |
|
232 while( ret.length() < KInterpretSISExpectedSIDLength ) |
|
233 { |
|
234 ret.insert( 0, L"0" ); |
|
235 } |
|
236 |
|
237 while( ret2.length() < KInterpretSISCtlIndexLength ) |
|
238 { |
|
239 ret2.insert( 0, L"0" ); |
|
240 } |
|
241 |
|
242 ret.append(L"_"); |
|
243 ret += ret2 + (L".ctl"); |
|
244 |
|
245 return ret; |
|
246 } |
|
247 |
|
248 |
|
249 std::wstring StringUtils::EnsureDirectoryTerminated( const std::wstring& aDir ) |
|
250 { |
|
251 std::wstring ret = aDir; |
|
252 // |
|
253 if ( ret.length() == 0 ) |
|
254 { |
|
255 ret.insert( 0, KDirectorySeparator ); |
|
256 } |
|
257 else if ( ret[ ret.length() - 1 ] != KDirectorySeparator[ 0 ] ) |
|
258 { |
|
259 ret.append( KDirectorySeparator ); |
|
260 } |
|
261 // |
|
262 return ret; |
|
263 } |
|
264 |
|
265 /** |
|
266 Compares a candidate string to a wildcard string - one containing any number of the wildcard characters '*' and '?' |
|
267 e.g. z:\foo\bar\lang*.txt with z:\foo\bar\lang35.txt. |
|
268 |
|
269 The function returns TRUE if a match is found, or FALSE. |
|
270 */ |
|
271 bool StringUtils::WildcardCompare(const std::wstring& aWildCardFileName, const std::wstring& aFileName) |
|
272 { |
|
273 std::wstring::const_iterator wildCurr = aWildCardFileName.begin(); |
|
274 std::wstring::const_iterator wildEnd = aWildCardFileName.end(); |
|
275 |
|
276 std::wstring::const_iterator fileCurr = aFileName.begin(); |
|
277 std::wstring::const_iterator fileEnd = aFileName.end(); |
|
278 |
|
279 std::wstring::const_iterator currentPos = NULL; |
|
280 std::wstring::const_iterator afterPos = NULL; |
|
281 |
|
282 // handle the '?' wildcard |
|
283 while ((fileCurr != fileEnd) && (*wildCurr != L'*')) |
|
284 { |
|
285 if ((*wildCurr != *fileCurr) && (*wildCurr != L'?')) |
|
286 { |
|
287 // the current character is different (and not represented by ? or *) |
|
288 return false; |
|
289 } |
|
290 |
|
291 if (wildCurr != wildEnd) |
|
292 wildCurr++; |
|
293 |
|
294 if (fileCurr != fileEnd) |
|
295 fileCurr++; |
|
296 |
|
297 } |
|
298 |
|
299 // encountered the '*' wildcard |
|
300 while (fileCurr != fileEnd) |
|
301 { |
|
302 if (*wildCurr == L'*') |
|
303 { |
|
304 |
|
305 // get the next char after the '*' |
|
306 if (wildCurr != wildEnd) |
|
307 wildCurr++; |
|
308 |
|
309 if (wildCurr == wildEnd) |
|
310 { |
|
311 // abcd* - abcdefg. Matches the remaining characters |
|
312 return true; |
|
313 } |
|
314 |
|
315 afterPos = wildCurr; |
|
316 |
|
317 if (fileCurr != fileEnd) |
|
318 currentPos = fileCurr++; |
|
319 |
|
320 } |
|
321 // keep iterating until we come the character which starts after the '*' |
|
322 else if ((*wildCurr == *fileCurr) || (*wildCurr == L'?')) |
|
323 { |
|
324 if (wildCurr != wildEnd) |
|
325 wildCurr++; |
|
326 |
|
327 if (fileCurr != fileEnd) |
|
328 fileCurr++; |
|
329 } |
|
330 else |
|
331 { |
|
332 wildCurr = afterPos; |
|
333 |
|
334 if (currentPos != fileEnd) |
|
335 fileCurr = currentPos++; |
|
336 } |
|
337 } |
|
338 |
|
339 while (*wildCurr == L'*') |
|
340 { |
|
341 if (wildCurr != wildEnd) |
|
342 wildCurr++; |
|
343 } |
|
344 |
|
345 // if we end up with an empty wild card string, we have a match |
|
346 return (*wildCurr == *wildEnd); |
|
347 } |
|
348 |
|
349 /** |
|
350 Gets the filename and extension. |
|
351 |
|
352 This is in the form: |
|
353 |
|
354 filename.ext |
|
355 |
|
356 @return The filename and extension. |
|
357 */ |
|
358 std::wstring StringUtils::NameAndExt( const std::wstring& aFile ) |
|
359 { |
|
360 int pos = aFile.find_last_of(L"\\"); |
|
361 if (pos == std::wstring::npos) |
|
362 { |
|
363 return L""; |
|
364 } |
|
365 else |
|
366 { |
|
367 std::wstring extension(aFile.substr(pos+1)); |
|
368 return extension; |
|
369 } |
|
370 } |
|
371 |
|
372 /** |
|
373 Gets the drive letter and path. |
|
374 |
|
375 This is in the form |
|
376 |
|
377 drive-letter:\\path\\ |
|
378 |
|
379 Note that the drive letter is folded |
|
380 |
|
381 @return The drive and path. |
|
382 */ |
|
383 std::wstring StringUtils::DriveAndPath( const std::wstring& aFile ) |
|
384 { |
|
385 int pos = aFile.find_last_of(L"\\"); |
|
386 if (pos == std::wstring::npos) |
|
387 { |
|
388 return L""; |
|
389 } |
|
390 else |
|
391 { |
|
392 std::wstring extension(aFile.substr(0,pos+1)); |
|
393 return extension; |
|
394 } |
|
395 } |
|
396 |
|
397 /** |
|
398 Gets the path. |
|
399 |
|
400 The path is in the form: |
|
401 |
|
402 \\path\\ |
|
403 |
|
404 @return The path. It always begins and ends in a backslash. |
|
405 */ |
|
406 std::wstring StringUtils::Path( const std::wstring& aFile ) |
|
407 { |
|
408 int firstPos = aFile.find_first_of(L"\\"); |
|
409 int lastPos = aFile.find_last_of(L"\\"); |
|
410 |
|
411 if (lastPos >= firstPos) |
|
412 { |
|
413 std::wstring path(aFile.substr(firstPos,lastPos-1)); |
|
414 return path; |
|
415 } |
|
416 |
|
417 return L""; |
|
418 } |
|
419 |
|
420 /** |
|
421 Gets the filename. |
|
422 |
|
423 This is in the form |
|
424 |
|
425 filename |
|
426 |
|
427 @return The filename. |
|
428 */ |
|
429 std::wstring StringUtils::Name( const std::wstring& aFile ) |
|
430 { |
|
431 int startPos = aFile.find_last_of(L"\\"); |
|
432 int endPos = aFile.find_last_of(L"."); |
|
433 |
|
434 if (endPos > startPos) |
|
435 { |
|
436 std::wstring extension(aFile.substr(startPos+1,endPos)); |
|
437 return extension; |
|
438 } |
|
439 |
|
440 return L""; |
|
441 } |
|
442 |
|
443 /** |
|
444 Gets the extension. |
|
445 |
|
446 This is in the form: |
|
447 |
|
448 .extension |
|
449 |
|
450 @return The extension and preceding dot. |
|
451 */ |
|
452 std::wstring StringUtils::Ext( const std::wstring& aFile ) |
|
453 { |
|
454 int pos = aFile.find_last_of(L"."); |
|
455 if (pos == std::wstring::npos) |
|
456 { |
|
457 return L""; |
|
458 } |
|
459 else |
|
460 { |
|
461 std::wstring extension(aFile.substr(pos)); |
|
462 return extension; |
|
463 } |
|
464 } |