OLD | NEW |
| (Empty) |
1 // Copyright 2006-2009 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 // | |
16 // Iterator over persisted metrics | |
17 #include "persistent_iterator-win32.h" | |
18 | |
19 namespace stats_report { | |
20 | |
21 void PersistentMetricsIteratorWin32::Next() { | |
22 current_value_.reset(); | |
23 | |
24 // Try to open the top-level key if we didn't already. | |
25 if (NULL == key_.m_hKey) { | |
26 HKEY parent_key = is_machine_ ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | |
27 LONG err = key_.Open(parent_key, key_name_, KEY_READ); | |
28 if (err != ERROR_SUCCESS) | |
29 return; | |
30 } | |
31 | |
32 // Loop until we find a value | |
33 while (state_ != kFinished) { | |
34 if (NULL == sub_key_.m_hKey) { | |
35 const wchar_t *subkey_name = NULL; | |
36 switch (state_) { | |
37 case kUninitialized: | |
38 state_ = kCounts; | |
39 subkey_name = kCountsKeyName; | |
40 break; | |
41 case kCounts: | |
42 state_ = kTimings; | |
43 subkey_name = kTimingsKeyName; | |
44 break; | |
45 case kTimings: | |
46 state_ = kIntegers; | |
47 subkey_name = kIntegersKeyName; | |
48 break; | |
49 case kIntegers: | |
50 state_ = kBooleans; | |
51 subkey_name = kBooleansKeyName; | |
52 break; | |
53 case kBooleans: | |
54 state_ = kFinished; | |
55 break; | |
56 case kFinished: | |
57 break; | |
58 } | |
59 | |
60 if (NULL != subkey_name) { | |
61 LONG err = sub_key_.Open(key_, subkey_name, KEY_READ); | |
62 // go around the loop on error to try the next key type | |
63 if (ERROR_SUCCESS != err) | |
64 continue; | |
65 } | |
66 | |
67 // reset value enumeration | |
68 value_index_ = 0; | |
69 } | |
70 | |
71 if (state_ != kFinished) { | |
72 DCHECK(NULL != sub_key_.m_hKey); | |
73 CString wide_value_name; | |
74 DWORD value_name_len = 255; | |
75 DWORD value_type = 0; | |
76 BYTE buf[sizeof(TimingMetric::TimingData)]; | |
77 DWORD value_len = sizeof(buf); | |
78 | |
79 // Get the next key and value | |
80 LONG err = ::RegEnumValue(sub_key_, value_index_, | |
81 CStrBuf(wide_value_name, static_cast<int>(value_name_len)), | |
82 &value_name_len, | |
83 0, &value_type, | |
84 buf, &value_len); | |
85 | |
86 ++value_index_; | |
87 | |
88 if (ERROR_NO_MORE_ITEMS == err) { | |
89 // done with this subkey, go around again | |
90 sub_key_.Close(); | |
91 continue; | |
92 } else if (ERROR_SUCCESS != err) { | |
93 // some other error, broken into a separate case for ease of debugging | |
94 DCHECK(false && "Unexpected error during reg value enumeration"); | |
95 } else { | |
96 DCHECK(ERROR_SUCCESS == err); | |
97 | |
98 // convert value to ASCII | |
99 current_value_name_ = wide_value_name; | |
100 | |
101 switch (state_) { | |
102 case kCounts: | |
103 if (value_len != sizeof(int64)) | |
104 continue; | |
105 current_value_.reset(new CountMetric(current_value_name_ .GetString(), | |
106 *reinterpret_cast<int64*>(&buf[0]))); | |
107 break; | |
108 case kTimings: | |
109 if (value_len != sizeof(TimingMetric::TimingData)) | |
110 continue; | |
111 current_value_.reset(new TimingMetric(current_value_name_.GetString(), | |
112 *reinterpret_cast<TimingMetric::TimingData*>(&buf[0]))); | |
113 break; | |
114 case kIntegers: | |
115 if (value_len != sizeof(int64)) | |
116 continue; | |
117 current_value_.reset(new IntegerMetric( | |
118 current_value_name_.GetString(), | |
119 *reinterpret_cast<int64*>(&buf[0]))); | |
120 break; | |
121 case kBooleans: | |
122 if (value_len != sizeof(uint32)) | |
123 continue; | |
124 current_value_.reset(new BoolMetric(current_value_name_.GetString(), | |
125 *reinterpret_cast<uint32*>(&buf[0]))); | |
126 break; | |
127 default: | |
128 DCHECK(false && "Impossible state during reg value enumeration"); | |
129 break; | |
130 } | |
131 | |
132 if (current_value_.get()) | |
133 return; | |
134 } | |
135 } | |
136 } | |
137 } | |
138 | |
139 } // namespace stats_report | |
OLD | NEW |