Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: installer/src/installer-lib/process.h

Issue 4790070691233792: Case-insensitive string class (Closed)
Patch Set: Created March 30, 2014, 7:49 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: installer/src/installer-lib/process.h
===================================================================
--- a/installer/src/installer-lib/process.h
+++ b/installer/src/installer-lib/process.h
@@ -7,6 +7,8 @@
#include "handle.h"
+#include <string>
+#include <cctype>
#include <vector>
#include <set>
#include <algorithm>
@@ -15,42 +17,76 @@
#include <Windows.h>
#include <TlHelp32.h>
+//-------------------------------------------------------
+// wstring_ci: case-insensitive wide string
+//-------------------------------------------------------
-//-------------------------------------------------------
-// exe_name_set: case-insensitive wide-string set
-//-------------------------------------------------------
-int wcscmpi( const wchar_t * s1, const wchar_t * s2 ) ;
+/**
+ * Traits class for case-insensitive strings.
+ */
+template< class T >
Wladimir Palant 2014/03/31 05:58:35 Style nit: excessive whitespace. There should be n
+struct ci_traits: std::char_traits< T >
+{
+ static bool eq( T c1, T c2 )
+ {
+ return std::tolower( c1 ) == std::tolower( c2 ) ;
+ }
-struct exe_name
-{
+ static bool lt( T c1, T c2 )
+ {
+ return std::tolower( c1 ) < std::tolower( c2 ) ;
+ }
+
/**
- * Pointer to wide-character string, which is supposed to be null-terminated.
+ * Trait comparison function.
+ *
+ * Note that this is not a comparison of C-style strings.
+ * In particular, there's no concern over null characters '\0'.
+ * The argument 'n' is the minimum length of the two strings being compared.
+ * We may assume that the intervals p1[0..n) and p2[0..n) are both valid substrings.
*/
- const wchar_t * name ;
-
- exe_name( const wchar_t * name ) : name( name ) {} ;
-} ;
-
-template <>
-struct std::less< exe_name >
- : std::binary_function< exe_name, exe_name, bool >
-{
- bool operator()( const exe_name & a, const exe_name & b ) const
+ static int compare( const T * p1, const T * p2, size_t n )
Oleksandr 2014/03/31 07:03:03 Once again, I think it would be much easier to jus
Wladimir Palant 2014/03/31 09:33:34 That's the standard way of doing this actually. Wh
Eric 2014/03/31 14:13:54 It would work, obviously, since that's what we wer
{
- return wcscmpi( a.name, b.name ) < 0 ;
+ while ( n-- > 0 )
Wladimir Palant 2014/03/31 05:58:35 Style nit: excessive whitespace. There should be n
+ {
+ T l1 = std::tolower( * p1 ++ ) ;
+ T l2 = std::tolower( * p2 ++ ) ;
Wladimir Palant 2014/03/31 05:58:35 Style nit: excessive whitespace. There should be n
+ if ( l1 == l2 )
+ {
+ continue ;
Wladimir Palant 2014/03/31 09:33:34 Didn't notice it originally - please use spaces fo
Eric 2014/03/31 14:13:54 That's Visual Studio acting up again. I thought I
+ }
+ return ( l1 < l2 ) ? -1 : +1 ;
+ }
+ return 0 ;
}
} ;
-struct exe_name_set
- : public std::set< exe_name >
+typedef std::basic_string< wchar_t, ci_traits< wchar_t > > wstring_ci ;
+
+
+//-------------------------------------------------------
+// file_name_set: case-insensitive wide-string set
+//-------------------------------------------------------
+struct file_name_set
+ : public std::set< wstring_ci >
{
- exe_name_set( const wchar_t * exe_name_list[], size_t n_exe_names )
+ /**
+ * Constructor initialization from an array.
+ */
+ template< size_t n_file_names >
+ file_name_set( const wchar_t * ( & file_name_list )[ n_file_names ] )
Wladimir Palant 2014/03/31 05:58:35 Style nit: excessive whitespace. There should be n
Wladimir Palant 2014/03/31 05:58:35 We might want to have a non-templated version of t
Eric 2014/03/31 14:13:54 We're also getting an empty-set constructor for th
{
- for ( unsigned int j = 0 ; j < n_exe_names ; ++ j )
+ for ( unsigned int j = 0 ; j < n_file_names ; ++ j )
{
- insert( exe_name( exe_name_list[ j ] ) ) ;
+ insert( wstring_ci( file_name_list[ j ] ) ) ;
}
}
+
+ /**
+ * Empty set constructor has no arguments.
+ */
+ file_name_set()
+ {}
Wladimir Palant 2014/03/31 05:58:35 Style nit: closing bracket should go on a new line
} ;
//-------------------------------------------------------
@@ -61,10 +97,14 @@
class process_by_any_exe_name_CI
: public std::unary_function< PROCESSENTRY32W, bool >
{
- const exe_name_set & names ;
+ const file_name_set & names ;
Wladimir Palant 2014/03/31 05:58:35 Please don't use references as class members, crea
Eric 2014/03/31 14:13:54 In this case, we can. This class is entirely subor
public:
- bool operator()( const PROCESSENTRY32W & ) ;
- process_by_any_exe_name_CI( const exe_name_set & names )
+ bool operator()( const PROCESSENTRY32W & process )
+ {
+ return names.find( process.szExeFile ) != names.end() ;
+ }
Wladimir Palant 2014/03/31 05:58:35 Nothing wrong with keeping implementations out of
Eric 2014/03/31 14:13:54 No, there's not. There's nothing wrong with puttin
+
+ process_by_any_exe_name_CI( const file_name_set & names )
: names( names )
{}
} ;
@@ -82,20 +122,6 @@
} ;
/**
- * Filter by process name. Comparison is case-insensitive.
- */
-class process_by_name_CI
- : public std::unary_function< PROCESSENTRY32W, bool >
-{
- const wchar_t * name ;
- const size_t length ;
- process_by_name_CI() ;
-public:
- bool operator()( const PROCESSENTRY32W & ) ;
- process_by_name_CI( const wchar_t * name ) ;
-} ;
-
-/**
* Extractor that copies the entire process structure.
*/
struct copy_all
@@ -114,11 +140,6 @@
} ;
/**
- * Case-insensitive wide-character C-style string comparison, fixed-length
- */
-int wcsncmpi( const wchar_t * a, const wchar_t * b, unsigned int length ) ;
-
-/**
* Retrieve the process ID that created a window.
*
* Wrapper around GetWindowThreadProcessId.
@@ -431,7 +452,7 @@
* The argument of the filter constructor is a set by reference.
* Since it does not make a copy for itself, we define it as a class member to provide its allocation.
*/
- exe_name_set exe_names ;
+ file_name_set process_names ;
/**
* Filter function object matches on any of the exe names specified in the constructor.
@@ -487,8 +508,9 @@
} ;
public:
- Process_Closer( Snapshot & snapshot, const wchar_t * exe_name_list[], size_t n_exe_names )
- : snapshot( snapshot ), exe_names( exe_name_list, n_exe_names ), filter( exe_names )
+ template< size_t n_process_names >
+ Process_Closer( Snapshot & snapshot, const wchar_t * ( & process_name_list )[ n_process_names ] )
+ : snapshot( snapshot ), process_names( process_name_list ), filter( process_names )
{
update() ;
}

Powered by Google App Engine
This is Rietveld