OLD | NEW |
| (Empty) |
1 // Copyright (c) 2007, Google Inc. | |
2 // All rights reserved. | |
3 // | |
4 // Redistribution and use in source and binary forms, with or without | |
5 // modification, are permitted provided that the following conditions are | |
6 // met: | |
7 // | |
8 // * Redistributions of source code must retain the above copyright | |
9 // notice, this list of conditions and the following disclaimer. | |
10 // * Redistributions in binary form must reproduce the above | |
11 // copyright notice, this list of conditions and the following disclaimer | |
12 // in the documentation and/or other materials provided with the | |
13 // distribution. | |
14 // * Neither the name of Google Inc. nor the names of its | |
15 // contributors may be used to endorse or promote products derived from | |
16 // this software without specific prior written permission. | |
17 // | |
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 // | |
30 // SimpleStringDictionary.h | |
31 // | |
32 | |
33 #ifndef SimpleStringDictionary_H__ | |
34 #define SimpleStringDictionary_H__ | |
35 | |
36 #import <string> | |
37 #import <vector> | |
38 | |
39 namespace google_breakpad { | |
40 | |
41 //============================================================================== | |
42 // SimpleStringDictionary (and associated class KeyValueEntry) implement a very | |
43 // basic dictionary container class. It has the property of not making any | |
44 // memory allocations when getting and setting values. But it is not very | |
45 // efficient, with calls to get and set values operating in linear time. | |
46 // It has the additional limitation of having a fairly small fixed capacity of | |
47 // SimpleStringDictionary::MAX_NUM_ENTRIES entries. An assert() will fire if | |
48 // the client attempts to set more than this number of key/value pairs. | |
49 // Ordinarilly a C++ programmer would use something like the std::map template | |
50 // class, or on the Macintosh would often choose CFDictionary or NSDictionary. | |
51 // But these dictionary classes may call malloc() during get and set operations. | |
52 // Google Breakpad requires that no memory allocations be made in code running | |
53 // in its exception handling thread, so it uses SimpleStringDictionary as the | |
54 // underlying implementation for the GoogleBreakpad.framework APIs: | |
55 // GoogleBreakpadSetKeyValue(), GoogleBreakpadKeyValue(), and | |
56 // GoogleBreakpadRemoveKeyValue() | |
57 // | |
58 | |
59 //============================================================================== | |
60 // KeyValueEntry | |
61 // | |
62 // A helper class used by SimpleStringDictionary representing a single | |
63 // storage cell for a key/value pair. Each key and value string are | |
64 // limited to MAX_STRING_STORAGE_SIZE-1 bytes (not glyphs). This class | |
65 // performs no memory allocations. It has methods for setting and getting | |
66 // key and value strings. | |
67 // | |
68 class KeyValueEntry { | |
69 public: | |
70 KeyValueEntry() { | |
71 Clear(); | |
72 } | |
73 | |
74 KeyValueEntry(const char *key, const char *value) { | |
75 SetKeyValue(key, value); | |
76 } | |
77 | |
78 void SetKeyValue(const char *key, const char *value) { | |
79 if (!key) { | |
80 key = ""; | |
81 } | |
82 if (!value) { | |
83 value = ""; | |
84 } | |
85 | |
86 strlcpy(key_, key, sizeof(key_)); | |
87 strlcpy(value_, value, sizeof(value_)); | |
88 } | |
89 | |
90 void SetValue(const char *value) { | |
91 if (!value) { | |
92 value = ""; | |
93 } | |
94 strlcpy(value_, value, sizeof(value_)); | |
95 }; | |
96 | |
97 // Removes the key/value | |
98 void Clear() { | |
99 memset(key_, 0, sizeof(key_)); | |
100 memset(value_, 0, sizeof(value_)); | |
101 } | |
102 | |
103 bool IsActive() const { return key_[0] != '\0'; } | |
104 const char *GetKey() const { return key_; } | |
105 const char *GetValue() const { return value_; } | |
106 | |
107 // Don't change this without considering the fixed size | |
108 // of MachMessage (in MachIPC.h) | |
109 // (see also struct KeyValueMessageData in Inspector.h) | |
110 enum {MAX_STRING_STORAGE_SIZE = 256}; | |
111 | |
112 private: | |
113 char key_[MAX_STRING_STORAGE_SIZE]; | |
114 char value_[MAX_STRING_STORAGE_SIZE]; | |
115 }; | |
116 | |
117 //============================================================================== | |
118 // This class is not an efficient dictionary, but for the purposes of breakpad | |
119 // will be just fine. We're just dealing with ten or so distinct | |
120 // key/value pairs. The idea is to avoid any malloc() or free() calls | |
121 // in certain important methods to be called when a process is in a | |
122 // crashed state. Each key and value string are limited to | |
123 // KeyValueEntry::MAX_STRING_STORAGE_SIZE-1 bytes (not glyphs). Strings passed | |
124 // in exceeding this length will be truncated. | |
125 // | |
126 class SimpleStringDictionary { | |
127 public: | |
128 SimpleStringDictionary() {}; // entries will all be cleared | |
129 | |
130 // Returns the number of active key/value pairs. The upper limit for this | |
131 // is MAX_NUM_ENTRIES. | |
132 int GetCount() const; | |
133 | |
134 // Given |key|, returns its corresponding |value|. | |
135 // If |key| is NULL, an assert will fire or NULL will be returned. If |key| | |
136 // is not found or is an empty string, NULL is returned. | |
137 const char *GetValueForKey(const char *key); | |
138 | |
139 // Stores a string |value| represented by |key|. If |key| is NULL or an empty | |
140 // string, this will assert (or do nothing). If |value| is NULL then | |
141 // the |key| will be removed. An empty string is OK for |value|. | |
142 void SetKeyValue(const char *key, const char *value); | |
143 | |
144 // Given |key|, removes any associated value. It will assert (or do nothing) | |
145 // if NULL is passed in. It will do nothing if |key| is not found. | |
146 void RemoveKey(const char *key); | |
147 | |
148 // This is the maximum number of key/value pairs which may be set in the | |
149 // dictionary. An assert may fire if more values than this are set. | |
150 // Don't change this without also changing comment in GoogleBreakpad.h | |
151 enum {MAX_NUM_ENTRIES = 64}; | |
152 | |
153 private: | |
154 friend class SimpleStringDictionaryIterator; | |
155 | |
156 const KeyValueEntry *GetEntry(int i) const; | |
157 | |
158 KeyValueEntry entries_[MAX_NUM_ENTRIES]; | |
159 }; | |
160 | |
161 //============================================================================== | |
162 class SimpleStringDictionaryIterator { | |
163 public: | |
164 SimpleStringDictionaryIterator(const SimpleStringDictionary &dict) | |
165 : dict_(dict), i_(0) { | |
166 } | |
167 | |
168 // Initializes iterator to the beginning (may later call Next() ) | |
169 void Start() { | |
170 i_ = 0; | |
171 } | |
172 | |
173 // like the nextObject method of NSEnumerator (in Cocoa) | |
174 // returns NULL when there are no more entries | |
175 // | |
176 const KeyValueEntry* Next() { | |
177 for (; i_ < SimpleStringDictionary::MAX_NUM_ENTRIES; ++i_) { | |
178 const KeyValueEntry *entry = dict_.GetEntry(i_); | |
179 if (entry->IsActive()) { | |
180 i_++; // move to next entry for next time | |
181 return entry; | |
182 } | |
183 } | |
184 | |
185 return NULL; // reached end of array | |
186 } | |
187 | |
188 private: | |
189 const SimpleStringDictionary& dict_; | |
190 int i_; | |
191 }; | |
192 | |
193 } // namespace google_breakpad | |
194 | |
195 #endif // SimpleStringDictionary_H__ | |
OLD | NEW |