| 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 |