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

Side by Side Diff: installer/src/installer-lib/process.h

Issue 4790070691233792: Case-insensitive string class (Closed)
Patch Set: Created March 30, 2014, 7:49 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /** 1 /**
2 * \file process.h 2 * \file process.h
3 */ 3 */
4 4
5 #ifndef PROCESS_H 5 #ifndef PROCESS_H
6 #define PROCESS_H 6 #define PROCESS_H
7 7
8 #include "handle.h" 8 #include "handle.h"
9 9
10 #include <string>
11 #include <cctype>
10 #include <vector> 12 #include <vector>
11 #include <set> 13 #include <set>
12 #include <algorithm> 14 #include <algorithm>
13 #include <memory> 15 #include <memory>
14 16
15 #include <Windows.h> 17 #include <Windows.h>
16 #include <TlHelp32.h> 18 #include <TlHelp32.h>
17 19
20 //-------------------------------------------------------
21 // wstring_ci: case-insensitive wide string
22 //-------------------------------------------------------
18 23
19 //------------------------------------------------------- 24 /**
20 // exe_name_set: case-insensitive wide-string set 25 * Traits class for case-insensitive strings.
21 //------------------------------------------------------- 26 */
22 int wcscmpi( const wchar_t * s1, const wchar_t * s2 ) ; 27 template< class T >
Wladimir Palant 2014/03/31 05:58:35 Style nit: excessive whitespace. There should be n
28 struct ci_traits: std::char_traits< T >
29 {
30 static bool eq( T c1, T c2 )
31 {
32 return std::tolower( c1 ) == std::tolower( c2 ) ;
33 }
23 34
24 struct exe_name 35 static bool lt( T c1, T c2 )
25 { 36 {
37 return std::tolower( c1 ) < std::tolower( c2 ) ;
38 }
39
26 /** 40 /**
27 * Pointer to wide-character string, which is supposed to be null-terminated. 41 * Trait comparison function.
42 *
43 * Note that this is not a comparison of C-style strings.
44 * In particular, there's no concern over null characters '\0'.
45 * The argument 'n' is the minimum length of the two strings being compared.
46 * We may assume that the intervals p1[0..n) and p2[0..n) are both valid subst rings.
28 */ 47 */
29 const wchar_t * name ; 48 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
30
31 exe_name( const wchar_t * name ) : name( name ) {} ;
32 } ;
33
34 template <>
35 struct std::less< exe_name >
36 : std::binary_function< exe_name, exe_name, bool >
37 {
38 bool operator()( const exe_name & a, const exe_name & b ) const
39 { 49 {
40 return wcscmpi( a.name, b.name ) < 0 ; 50 while ( n-- > 0 )
Wladimir Palant 2014/03/31 05:58:35 Style nit: excessive whitespace. There should be n
51 {
52 T l1 = std::tolower( * p1 ++ ) ;
53 T l2 = std::tolower( * p2 ++ ) ;
Wladimir Palant 2014/03/31 05:58:35 Style nit: excessive whitespace. There should be n
54 if ( l1 == l2 )
55 {
56 » 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
57 }
58 return ( l1 < l2 ) ? -1 : +1 ;
59 }
60 return 0 ;
41 } 61 }
42 } ; 62 } ;
43 63
44 struct exe_name_set 64 typedef std::basic_string< wchar_t, ci_traits< wchar_t > > wstring_ci ;
45 : public std::set< exe_name > 65
66
67 //-------------------------------------------------------
68 // file_name_set: case-insensitive wide-string set
69 //-------------------------------------------------------
70 struct file_name_set
71 : public std::set< wstring_ci >
46 { 72 {
47 exe_name_set( const wchar_t * exe_name_list[], size_t n_exe_names ) 73 /**
74 * Constructor initialization from an array.
75 */
76 template< size_t n_file_names >
77 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
48 { 78 {
49 for ( unsigned int j = 0 ; j < n_exe_names ; ++ j ) 79 for ( unsigned int j = 0 ; j < n_file_names ; ++ j )
50 { 80 {
51 insert( exe_name( exe_name_list[ j ] ) ) ; 81 insert( wstring_ci( file_name_list[ j ] ) ) ;
52 } 82 }
53 } 83 }
84
85 /**
86 * Empty set constructor has no arguments.
87 */
88 file_name_set()
89 {}
Wladimir Palant 2014/03/31 05:58:35 Style nit: closing bracket should go on a new line
54 } ; 90 } ;
55 91
56 //------------------------------------------------------- 92 //-------------------------------------------------------
57 //------------------------------------------------------- 93 //-------------------------------------------------------
58 /** 94 /**
59 * Filter by process name. Comparison is case-insensitive. 95 * Filter by process name. Comparison is case-insensitive.
60 */ 96 */
61 class process_by_any_exe_name_CI 97 class process_by_any_exe_name_CI
62 : public std::unary_function< PROCESSENTRY32W, bool > 98 : public std::unary_function< PROCESSENTRY32W, bool >
63 { 99 {
64 const exe_name_set & names ; 100 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
65 public: 101 public:
66 bool operator()( const PROCESSENTRY32W & ) ; 102 bool operator()( const PROCESSENTRY32W & process )
67 process_by_any_exe_name_CI( const exe_name_set & names ) 103 {
104 return names.find( process.szExeFile ) != names.end() ;
105 }
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
106
107 process_by_any_exe_name_CI( const file_name_set & names )
68 : names( names ) 108 : names( names )
69 {} 109 {}
70 } ; 110 } ;
71 111
72 //------------------------------------------------------- 112 //-------------------------------------------------------
73 // Process utility functions. 113 // Process utility functions.
74 //------------------------------------------------------- 114 //-------------------------------------------------------
75 /** 115 /**
76 * A promiscuous filter admits everything. 116 * A promiscuous filter admits everything.
77 */ 117 */
78 struct every_process 118 struct every_process
79 : public std::unary_function< PROCESSENTRY32W, bool > 119 : public std::unary_function< PROCESSENTRY32W, bool >
80 { 120 {
81 bool operator()( const PROCESSENTRY32W & ) { return true ; } ; 121 bool operator()( const PROCESSENTRY32W & ) { return true ; } ;
82 } ; 122 } ;
83 123
84 /** 124 /**
85 * Filter by process name. Comparison is case-insensitive.
86 */
87 class process_by_name_CI
88 : public std::unary_function< PROCESSENTRY32W, bool >
89 {
90 const wchar_t * name ;
91 const size_t length ;
92 process_by_name_CI() ;
93 public:
94 bool operator()( const PROCESSENTRY32W & ) ;
95 process_by_name_CI( const wchar_t * name ) ;
96 } ;
97
98 /**
99 * Extractor that copies the entire process structure. 125 * Extractor that copies the entire process structure.
100 */ 126 */
101 struct copy_all 127 struct copy_all
102 : public std::unary_function< PROCESSENTRY32W, PROCESSENTRY32W > 128 : public std::unary_function< PROCESSENTRY32W, PROCESSENTRY32W >
103 { 129 {
104 PROCESSENTRY32W operator()( const PROCESSENTRY32W & process ) { return process ; } 130 PROCESSENTRY32W operator()( const PROCESSENTRY32W & process ) { return process ; }
105 } ; 131 } ;
106 132
107 /** 133 /**
108 * Extractor that copies only the PID. 134 * Extractor that copies only the PID.
109 */ 135 */
110 struct copy_PID 136 struct copy_PID
111 : public std::unary_function< PROCESSENTRY32W, DWORD > 137 : public std::unary_function< PROCESSENTRY32W, DWORD >
112 { 138 {
113 inline DWORD operator()( const PROCESSENTRY32W & process ) { return process.th 32ProcessID ; } 139 inline DWORD operator()( const PROCESSENTRY32W & process ) { return process.th 32ProcessID ; }
114 } ; 140 } ;
115 141
116 /** 142 /**
117 * Case-insensitive wide-character C-style string comparison, fixed-length
118 */
119 int wcsncmpi( const wchar_t * a, const wchar_t * b, unsigned int length ) ;
120
121 /**
122 * Retrieve the process ID that created a window. 143 * Retrieve the process ID that created a window.
123 * 144 *
124 * Wrapper around GetWindowThreadProcessId. 145 * Wrapper around GetWindowThreadProcessId.
125 * Converts an error return from the system call into an exception. 146 * Converts an error return from the system call into an exception.
126 * The system call can also retrieve the creating thread; we ignore it. 147 * The system call can also retrieve the creating thread; we ignore it.
127 * 148 *
128 * \param window 149 * \param window
129 * Handle of the window 150 * Handle of the window
130 * \return 151 * \return
131 * ID of the process that created the argument window 152 * ID of the process that created the argument window
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 * Set of process identifiers matching one of the executable names. 445 * Set of process identifiers matching one of the executable names.
425 */ 446 */
426 std::set< DWORD > pid_set ; 447 std::set< DWORD > pid_set ;
427 448
428 /** 449 /**
429 * Set of executable names by which to filter. 450 * Set of executable names by which to filter.
430 * 451 *
431 * The argument of the filter constructor is a set by reference. 452 * The argument of the filter constructor is a set by reference.
432 * Since it does not make a copy for itself, we define it as a class member to provide its allocation. 453 * Since it does not make a copy for itself, we define it as a class member to provide its allocation.
433 */ 454 */
434 exe_name_set exe_names ; 455 file_name_set process_names ;
435 456
436 /** 457 /**
437 * Filter function object matches on any of the exe names specified in the con structor. 458 * Filter function object matches on any of the exe names specified in the con structor.
438 */ 459 */
439 process_by_any_exe_name_CI filter ; 460 process_by_any_exe_name_CI filter ;
440 461
441 /** 462 /**
442 * Copy function object copies just the process ID. 463 * Copy function object copies just the process ID.
443 */ 464 */
444 copy_PID copy ; 465 copy_PID copy ;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 if ( ! b ) 501 if ( ! b )
481 { 502 {
482 // Assert the process that created the window is not in our pid_set 503 // Assert the process that created the window is not in our pid_set
483 return true ; 504 return true ;
484 } 505 }
485 return f( window ) ; 506 return f( window ) ;
486 } 507 }
487 } ; 508 } ;
488 509
489 public: 510 public:
490 Process_Closer( Snapshot & snapshot, const wchar_t * exe_name_list[], size_t n _exe_names ) 511 template< size_t n_process_names >
491 : snapshot( snapshot ), exe_names( exe_name_list, n_exe_names ), filter( exe _names ) 512 Process_Closer( Snapshot & snapshot, const wchar_t * ( & process_name_list )[ n_process_names ] )
513 : snapshot( snapshot ), process_names( process_name_list ), filter( process_ names )
492 { 514 {
493 update() ; 515 update() ;
494 } 516 }
495 517
496 /** 518 /**
497 * Refresh our state to match the snapshot state. 519 * Refresh our state to match the snapshot state.
498 */ 520 */
499 void refresh() 521 void refresh()
500 { 522 {
501 pid_set.clear() ; 523 pid_set.clear() ;
(...skipping 12 matching lines...) Expand all
514 } 536 }
515 537
516 /* 538 /*
517 * Shut down every process in the pid_set. 539 * Shut down every process in the pid_set.
518 */ 540 */
519 bool shut_down() ; 541 bool shut_down() ;
520 542
521 } ; 543 } ;
522 544
523 #endif 545 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld