1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/common/mac/SimpleStringDictionary.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,195 @@ 1.4 +// Copyright (c) 2007, Google Inc. 1.5 +// All rights reserved. 1.6 +// 1.7 +// Redistribution and use in source and binary forms, with or without 1.8 +// modification, are permitted provided that the following conditions are 1.9 +// met: 1.10 +// 1.11 +// * Redistributions of source code must retain the above copyright 1.12 +// notice, this list of conditions and the following disclaimer. 1.13 +// * Redistributions in binary form must reproduce the above 1.14 +// copyright notice, this list of conditions and the following disclaimer 1.15 +// in the documentation and/or other materials provided with the 1.16 +// distribution. 1.17 +// * Neither the name of Google Inc. nor the names of its 1.18 +// contributors may be used to endorse or promote products derived from 1.19 +// this software without specific prior written permission. 1.20 +// 1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 +// 1.33 +// SimpleStringDictionary.h 1.34 +// 1.35 + 1.36 +#ifndef SimpleStringDictionary_H__ 1.37 +#define SimpleStringDictionary_H__ 1.38 + 1.39 +#import <string> 1.40 +#import <vector> 1.41 + 1.42 +namespace google_breakpad { 1.43 + 1.44 +//============================================================================== 1.45 +// SimpleStringDictionary (and associated class KeyValueEntry) implement a very 1.46 +// basic dictionary container class. It has the property of not making any 1.47 +// memory allocations when getting and setting values. But it is not very 1.48 +// efficient, with calls to get and set values operating in linear time. 1.49 +// It has the additional limitation of having a fairly small fixed capacity of 1.50 +// SimpleStringDictionary::MAX_NUM_ENTRIES entries. An assert() will fire if 1.51 +// the client attempts to set more than this number of key/value pairs. 1.52 +// Ordinarilly a C++ programmer would use something like the std::map template 1.53 +// class, or on the Macintosh would often choose CFDictionary or NSDictionary. 1.54 +// But these dictionary classes may call malloc() during get and set operations. 1.55 +// Google Breakpad requires that no memory allocations be made in code running 1.56 +// in its exception handling thread, so it uses SimpleStringDictionary as the 1.57 +// underlying implementation for the GoogleBreakpad.framework APIs: 1.58 +// GoogleBreakpadSetKeyValue(), GoogleBreakpadKeyValue(), and 1.59 +// GoogleBreakpadRemoveKeyValue() 1.60 +// 1.61 + 1.62 +//============================================================================== 1.63 +// KeyValueEntry 1.64 +// 1.65 +// A helper class used by SimpleStringDictionary representing a single 1.66 +// storage cell for a key/value pair. Each key and value string are 1.67 +// limited to MAX_STRING_STORAGE_SIZE-1 bytes (not glyphs). This class 1.68 +// performs no memory allocations. It has methods for setting and getting 1.69 +// key and value strings. 1.70 +// 1.71 +class KeyValueEntry { 1.72 + public: 1.73 + KeyValueEntry() { 1.74 + Clear(); 1.75 + } 1.76 + 1.77 + KeyValueEntry(const char *key, const char *value) { 1.78 + SetKeyValue(key, value); 1.79 + } 1.80 + 1.81 + void SetKeyValue(const char *key, const char *value) { 1.82 + if (!key) { 1.83 + key = ""; 1.84 + } 1.85 + if (!value) { 1.86 + value = ""; 1.87 + } 1.88 + 1.89 + strlcpy(key_, key, sizeof(key_)); 1.90 + strlcpy(value_, value, sizeof(value_)); 1.91 + } 1.92 + 1.93 + void SetValue(const char *value) { 1.94 + if (!value) { 1.95 + value = ""; 1.96 + } 1.97 + strlcpy(value_, value, sizeof(value_)); 1.98 + }; 1.99 + 1.100 + // Removes the key/value 1.101 + void Clear() { 1.102 + memset(key_, 0, sizeof(key_)); 1.103 + memset(value_, 0, sizeof(value_)); 1.104 + } 1.105 + 1.106 + bool IsActive() const { return key_[0] != '\0'; } 1.107 + const char *GetKey() const { return key_; } 1.108 + const char *GetValue() const { return value_; } 1.109 + 1.110 + // Don't change this without considering the fixed size 1.111 + // of MachMessage (in MachIPC.h) 1.112 + // (see also struct KeyValueMessageData in Inspector.h) 1.113 + enum {MAX_STRING_STORAGE_SIZE = 256}; 1.114 + 1.115 + private: 1.116 + char key_[MAX_STRING_STORAGE_SIZE]; 1.117 + char value_[MAX_STRING_STORAGE_SIZE]; 1.118 +}; 1.119 + 1.120 +//============================================================================== 1.121 +// This class is not an efficient dictionary, but for the purposes of breakpad 1.122 +// will be just fine. We're just dealing with ten or so distinct 1.123 +// key/value pairs. The idea is to avoid any malloc() or free() calls 1.124 +// in certain important methods to be called when a process is in a 1.125 +// crashed state. Each key and value string are limited to 1.126 +// KeyValueEntry::MAX_STRING_STORAGE_SIZE-1 bytes (not glyphs). Strings passed 1.127 +// in exceeding this length will be truncated. 1.128 +// 1.129 +class SimpleStringDictionary { 1.130 + public: 1.131 + SimpleStringDictionary() {}; // entries will all be cleared 1.132 + 1.133 + // Returns the number of active key/value pairs. The upper limit for this 1.134 + // is MAX_NUM_ENTRIES. 1.135 + int GetCount() const; 1.136 + 1.137 + // Given |key|, returns its corresponding |value|. 1.138 + // If |key| is NULL, an assert will fire or NULL will be returned. If |key| 1.139 + // is not found or is an empty string, NULL is returned. 1.140 + const char *GetValueForKey(const char *key) const; 1.141 + 1.142 + // Stores a string |value| represented by |key|. If |key| is NULL or an empty 1.143 + // string, this will assert (or do nothing). If |value| is NULL then 1.144 + // the |key| will be removed. An empty string is OK for |value|. 1.145 + void SetKeyValue(const char *key, const char *value); 1.146 + 1.147 + // Given |key|, removes any associated value. It will assert (or do nothing) 1.148 + // if NULL is passed in. It will do nothing if |key| is not found. 1.149 + void RemoveKey(const char *key); 1.150 + 1.151 + // This is the maximum number of key/value pairs which may be set in the 1.152 + // dictionary. An assert may fire if more values than this are set. 1.153 + // Don't change this without also changing comment in GoogleBreakpad.h 1.154 + enum {MAX_NUM_ENTRIES = 64}; 1.155 + 1.156 + private: 1.157 + friend class SimpleStringDictionaryIterator; 1.158 + 1.159 + const KeyValueEntry *GetEntry(int i) const; 1.160 + 1.161 + KeyValueEntry entries_[MAX_NUM_ENTRIES]; 1.162 +}; 1.163 + 1.164 +//============================================================================== 1.165 +class SimpleStringDictionaryIterator { 1.166 + public: 1.167 + SimpleStringDictionaryIterator(const SimpleStringDictionary &dict) 1.168 + : dict_(dict), i_(0) { 1.169 + } 1.170 + 1.171 + // Initializes iterator to the beginning (may later call Next() ) 1.172 + void Start() { 1.173 + i_ = 0; 1.174 + } 1.175 + 1.176 + // like the nextObject method of NSEnumerator (in Cocoa) 1.177 + // returns NULL when there are no more entries 1.178 + // 1.179 + const KeyValueEntry* Next() { 1.180 + for (; i_ < SimpleStringDictionary::MAX_NUM_ENTRIES; ++i_) { 1.181 + const KeyValueEntry *entry = dict_.GetEntry(i_); 1.182 + if (entry->IsActive()) { 1.183 + i_++; // move to next entry for next time 1.184 + return entry; 1.185 + } 1.186 + } 1.187 + 1.188 + return NULL; // reached end of array 1.189 + } 1.190 + 1.191 + private: 1.192 + const SimpleStringDictionary& dict_; 1.193 + int i_; 1.194 +}; 1.195 + 1.196 +} // namespace google_breakpad 1.197 + 1.198 +#endif // SimpleStringDictionary_H__