Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1029)

Side by Side Diff: client/simple_string_dictionary.h

Issue 499643002: Convert SimpleStringDictionary interface documentation to Doxygen (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Address review feedback Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Crashpad Authors. All rights reserved. 1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with 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 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #ifndef CRASHPAD_CLIENT_SIMPLE_STRING_DICTIONARY_H_ 15 #ifndef CRASHPAD_CLIENT_SIMPLE_STRING_DICTIONARY_H_
16 #define CRASHPAD_CLIENT_SIMPLE_STRING_DICTIONARY_H_ 16 #define CRASHPAD_CLIENT_SIMPLE_STRING_DICTIONARY_H_
17 17
18 #include <string.h> 18 #include <string.h>
19 19
20 #include "base/basictypes.h" 20 #include "base/basictypes.h"
21 #include "base/logging.h" 21 #include "base/logging.h"
22 22
23 namespace crashpad { 23 namespace crashpad {
24 24
25 // Opaque type for the serialized representation of a TSimpleStringDictionary. 25 // Opaque type for the serialized representation of a TSimpleStringDictionary.
26 // One is created in TSimpleStringDictionary::Serialize and can be deserialized 26 // One is created in TSimpleStringDictionary::Serialize and can be deserialized
27 // using one of the constructors. 27 // using one of the constructors.
28 struct SerializedSimpleStringDictionary; 28 struct SerializedSimpleStringDictionary;
29 29
30 // TSimpleStringDictionary is an implementation of a map/dictionary collection 30 //! \brief A map/dictionary collection implementation using a fixed amount of
31 // that uses a fixed amount of storage, so that it does not perform any dynamic 31 //! storage, so that it does not perform any dynamic allocations for its
32 // allocations for its operations. 32 //! operations.
33 // 33 //!
34 // The actual map storage (the Entry) is guaranteed to be POD, so that it can be 34 //! The actual map storage (TSimpleStringDictionary::Entry) is guaranteed to be
35 // transmitted over various IPC mechanisms. 35 //! POD, so that it can be transmitted over various IPC mechanisms.
36 // 36 //!
37 // The template parameters control the amount of storage used for the key, 37 //! The template parameters control the amount of storage used for the key,
38 // value, and map. The KeySize and ValueSize are measured in bytes, not glyphs, 38 //! value, and map. The \a KeySize and \a ValueSize are measured in bytes, not
39 // and includes space for a \0 byte. This gives space for KeySize-1 and 39 //! glyphs, and include space for a trailing `NUL` byte. This gives space for
40 // ValueSize-1 characters in an entry. NumEntries is the total number of entries 40 //! `KeySize - 1` and `ValueSize - 1` characters in an entry. \a NumEntries is
41 // that will fit in the map. 41 //! the total number of entries that will fit in the map.
42 template <size_t KeySize = 256, size_t ValueSize = 256, size_t NumEntries = 64> 42 template <size_t KeySize = 256, size_t ValueSize = 256, size_t NumEntries = 64>
43 class TSimpleStringDictionary { 43 class TSimpleStringDictionary {
44 public: 44 public:
45 // Constant and publicly accessible versions of the template parameters. 45 //! \brief Constant and publicly accessible versions of the template
46 //! parameters.
47 //! \{
46 static const size_t key_size = KeySize; 48 static const size_t key_size = KeySize;
47 static const size_t value_size = ValueSize; 49 static const size_t value_size = ValueSize;
48 static const size_t num_entries = NumEntries; 50 static const size_t num_entries = NumEntries;
51 //! \}
49 52
50 // An Entry object is a single entry in the map. If the key is a 0-length 53 //! \brief A single entry in the map.
51 // NUL-terminated string, the entry is empty.
52 struct Entry { 54 struct Entry {
55 //! \brief The entry’s key.
56 //!
57 //! If this is a 0-length `NUL`-terminated string, the entry is inactive.
53 char key[KeySize]; 58 char key[KeySize];
59
60 //! \brief The entry’s value.
54 char value[ValueSize]; 61 char value[ValueSize];
55 62
63 //! \brief Returns the validity of the entry.
64 //!
65 //! If #key is an empty string, the entry is considered inactive, and this
66 //! method returns `false`. Otherwise, returns `true`.
56 bool is_active() const { 67 bool is_active() const {
57 return key[0] != '\0'; 68 return key[0] != '\0';
58 } 69 }
59 }; 70 };
60 71
61 // An Iterator can be used to iterate over all the active entries in a 72 //! \brief An iterator to traverse all of the active entries in a
62 // TSimpleStringDictionary. 73 //! TSimpleStringDictionary.
63 class Iterator { 74 class Iterator {
64 public: 75 public:
65 explicit Iterator(const TSimpleStringDictionary& map) 76 explicit Iterator(const TSimpleStringDictionary& map)
66 : map_(map), 77 : map_(map),
67 current_(0) { 78 current_(0) {
68 } 79 }
69 80
70 // Returns the next entry in the map, or NULL if at the end of the 81 //! \brief Returns the next entry in the map, or `NULL` if at the end of the
71 // collection. 82 //! collection.
72 const Entry* Next() { 83 const Entry* Next() {
73 while (current_ < map_.num_entries) { 84 while (current_ < map_.num_entries) {
74 const Entry* entry = &map_.entries_[current_++]; 85 const Entry* entry = &map_.entries_[current_++];
75 if (entry->is_active()) { 86 if (entry->is_active()) {
76 return entry; 87 return entry;
77 } 88 }
78 } 89 }
79 return NULL; 90 return NULL;
80 } 91 }
81 92
(...skipping 10 matching lines...) Expand all
92 103
93 TSimpleStringDictionary(const TSimpleStringDictionary& other) { 104 TSimpleStringDictionary(const TSimpleStringDictionary& other) {
94 *this = other; 105 *this = other;
95 } 106 }
96 107
97 TSimpleStringDictionary& operator=(const TSimpleStringDictionary& other) { 108 TSimpleStringDictionary& operator=(const TSimpleStringDictionary& other) {
98 memcpy(entries_, other.entries_, sizeof(entries_)); 109 memcpy(entries_, other.entries_, sizeof(entries_));
99 return *this; 110 return *this;
100 } 111 }
101 112
102 // Constructs a map from its serialized form. |map| should be the out 113 //! \brief Constructs a map from its serialized form. \a map should be the out
103 // parameter from Serialize() and |size| should be its return value. 114 //! parameter from Serialize(), and \a size should be its return value.
104 TSimpleStringDictionary( 115 TSimpleStringDictionary(
105 const SerializedSimpleStringDictionary* map, size_t size) { 116 const SerializedSimpleStringDictionary* map, size_t size) {
106 DCHECK_EQ(size, sizeof(entries_)); 117 DCHECK_EQ(size, sizeof(entries_));
107 if (size == sizeof(entries_)) { 118 if (size == sizeof(entries_)) {
108 memcpy(entries_, map, size); 119 memcpy(entries_, map, size);
109 } 120 }
110 } 121 }
111 122
112 // Returns the number of active key/value pairs. The upper limit for this is 123 //! \brief Returns the number of active key/value pairs. The upper limit for
113 // NumEntries. 124 //! this is \a NumEntries.
114 size_t GetCount() const { 125 size_t GetCount() const {
115 size_t count = 0; 126 size_t count = 0;
116 for (size_t i = 0; i < num_entries; ++i) { 127 for (size_t i = 0; i < num_entries; ++i) {
117 if (entries_[i].is_active()) { 128 if (entries_[i].is_active()) {
118 ++count; 129 ++count;
119 } 130 }
120 } 131 }
121 return count; 132 return count;
122 } 133 }
123 134
124 // Given |key|, returns its corresponding |value|. |key| must not be NULL. If 135 //! \brief Given \a key, returns its corresponding value.
125 // the key is not found, NULL is returned. 136 //!
137 //! \param[in] key The key to look up. This must not be `NULL`.
138 //!
139 //! \return The corresponding value for \a key, or if \a key is not found,
140 //! `NULL`.
126 const char* GetValueForKey(const char* key) const { 141 const char* GetValueForKey(const char* key) const {
127 DCHECK(key); 142 DCHECK(key);
128 if (!key) { 143 if (!key) {
129 return NULL; 144 return NULL;
130 } 145 }
131 146
132 const Entry* entry = GetConstEntryForKey(key); 147 const Entry* entry = GetConstEntryForKey(key);
133 if (!entry) { 148 if (!entry) {
134 return NULL; 149 return NULL;
135 } 150 }
136 151
137 return entry->value; 152 return entry->value;
138 } 153 }
139 154
140 // Stores |value| into |key|, replacing the existing value if |key| is already 155 //! \brief Stores \a value into \a key, replacing the existing value if \a key
141 // present. |key| must not be NULL. If |value| is NULL, the key is removed 156 //! is already present.
142 // from the map. If there is no more space in the map, then the operation 157 //!
143 // silently fails. 158 //! If there \a key is not yet in the map and the map is already full
159 //! (containing \a NumEntries active entries), this operation silently fails.
160 //!
161 //! \param[in] key The key to store. This must not be `NULL`.
162 //! \param[in] value The value to store. If `NULL`, \a key is removed from the
163 //! map.
144 void SetKeyValue(const char* key, const char* value) { 164 void SetKeyValue(const char* key, const char* value) {
145 if (!value) { 165 if (!value) {
146 RemoveKey(key); 166 RemoveKey(key);
147 return; 167 return;
148 } 168 }
149 169
150 DCHECK(key); 170 DCHECK(key);
151 if (!key) { 171 if (!key) {
152 return; 172 return;
153 } 173 }
154 174
155 // Key must not be an empty string. 175 // |key| must not be an empty string.
156 DCHECK_NE(key[0], '\0'); 176 DCHECK_NE(key[0], '\0');
157 if (key[0] == '\0') { 177 if (key[0] == '\0') {
158 return; 178 return;
159 } 179 }
160 180
161 Entry* entry = GetEntryForKey(key); 181 Entry* entry = GetEntryForKey(key);
162 182
163 // If it does not yet exist, attempt to insert it. 183 // If it does not yet exist, attempt to insert it.
164 if (!entry) { 184 if (!entry) {
165 for (size_t i = 0; i < num_entries; ++i) { 185 for (size_t i = 0; i < num_entries; ++i) {
(...skipping 21 matching lines...) Expand all
187 ++count; 207 ++count;
188 } 208 }
189 } 209 }
190 DCHECK_EQ(count, 1); 210 DCHECK_EQ(count, 1);
191 #endif 211 #endif
192 212
193 strncpy(entry->value, value, value_size); 213 strncpy(entry->value, value, value_size);
194 entry->value[value_size - 1] = '\0'; 214 entry->value[value_size - 1] = '\0';
195 } 215 }
196 216
197 // Given |key|, removes any associated value. |key| must not be NULL. If the 217 //! \brief Removes \a key from the map.
198 // key is not found, this is a noop. 218 //!
219 //! If the key is not found, this is a no-op.
220 //!
221 //! \param[in] key The key of the entry to remove. This must not be `NULL`.
199 void RemoveKey(const char* key) { 222 void RemoveKey(const char* key) {
200 DCHECK(key); 223 DCHECK(key);
201 if (!key) { 224 if (!key) {
202 return; 225 return;
203 } 226 }
204 227
205 Entry* entry = GetEntryForKey(key); 228 Entry* entry = GetEntryForKey(key);
206 if (entry) { 229 if (entry) {
207 entry->key[0] = '\0'; 230 entry->key[0] = '\0';
208 entry->value[0] = '\0'; 231 entry->value[0] = '\0';
209 } 232 }
210 233
211 DCHECK_EQ(GetEntryForKey(key), static_cast<void*>(NULL)); 234 DCHECK_EQ(GetEntryForKey(key), static_cast<void*>(NULL));
212 } 235 }
213 236
214 // Places a serialized version of the map into |map| and returns the size. 237 //! \brief Returns a serialized form of the map.
215 // Both of these should be passed to the deserializing constructor. Note that 238 //!
216 // the serialized |map| is scoped to the lifetime of the non-serialized 239 //! Places a serialized version of the map into \a map and returns the size in
217 // instance of this class. The |map| can be copied across IPC boundaries. 240 //! bytes. Both \a map and the size should be passed to the deserializing
241 //! constructor. Note that the serialized \a map is scoped to the lifetime of
242 //! the non-serialized instance of this class. The \a map data can be copied
243 //! across IPC boundaries.
218 size_t Serialize(const SerializedSimpleStringDictionary** map) const { 244 size_t Serialize(const SerializedSimpleStringDictionary** map) const {
219 *map = reinterpret_cast<const SerializedSimpleStringDictionary*>(entries_); 245 *map = reinterpret_cast<const SerializedSimpleStringDictionary*>(entries_);
220 return sizeof(entries_); 246 return sizeof(entries_);
221 } 247 }
222 248
223 private: 249 private:
224 const Entry* GetConstEntryForKey(const char* key) const { 250 const Entry* GetConstEntryForKey(const char* key) const {
225 for (size_t i = 0; i < num_entries; ++i) { 251 for (size_t i = 0; i < num_entries; ++i) {
226 if (strncmp(key, entries_[i].key, key_size) == 0) { 252 if (strncmp(key, entries_[i].key, key_size) == 0) {
227 return &entries_[i]; 253 return &entries_[i];
228 } 254 }
229 } 255 }
230 return NULL; 256 return NULL;
231 } 257 }
232 258
233 Entry* GetEntryForKey(const char* key) { 259 Entry* GetEntryForKey(const char* key) {
234 return const_cast<Entry*>(GetConstEntryForKey(key)); 260 return const_cast<Entry*>(GetConstEntryForKey(key));
235 } 261 }
236 262
237 Entry entries_[NumEntries]; 263 Entry entries_[NumEntries];
238 }; 264 };
239 265
240 // For historical reasons this specialized version is available with the same 266 //! \brief A TSimpleStringDictionary with default template parameters.
241 // size factors as a previous implementation. 267 //!
268 //! For historical reasons this specialized version is available with the same
269 //! size factors as a previous implementation.
242 typedef TSimpleStringDictionary<256, 256, 64> SimpleStringDictionary; 270 typedef TSimpleStringDictionary<256, 256, 64> SimpleStringDictionary;
243 271
244 } // namespace crashpad 272 } // namespace crashpad
245 273
246 #endif // CRASHPAD_CLIENT_SIMPLE_STRING_DICTIONARY_H_ 274 #endif // CRASHPAD_CLIENT_SIMPLE_STRING_DICTIONARY_H_
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698