simple_string_dictionary.h revision 303311b8370b307ea38201fc3ad241a5610f8cfc
13ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Copyright (c) 2007, Google Inc. 23ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// All rights reserved. 33ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 43ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Redistribution and use in source and binary forms, with or without 53ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// modification, are permitted provided that the following conditions are 63ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// met: 73ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 83ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// * Redistributions of source code must retain the above copyright 93ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// notice, this list of conditions and the following disclaimer. 103ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// * Redistributions in binary form must reproduce the above 113ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// copyright notice, this list of conditions and the following disclaimer 123ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// in the documentation and/or other materials provided with the 133ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// distribution. 143ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// * Neither the name of Google Inc. nor the names of its 153ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// contributors may be used to endorse or promote products derived from 163ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// this software without specific prior written permission. 173ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 183ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 193ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 203ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 213ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 223ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 233ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 243ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 253ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 263ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 273ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 283ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 293ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 30303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org#ifndef COMMON_SIMPLE_STRING_DICTIONARY_H_ 31303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org#define COMMON_SIMPLE_STRING_DICTIONARY_H_ 323ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 333ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#import <string> 343ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid#import <vector> 353ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 363ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidnamespace google_breakpad { 373ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 383ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 393ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// SimpleStringDictionary (and associated class KeyValueEntry) implement a very 403ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// basic dictionary container class. It has the property of not making any 413ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// memory allocations when getting and setting values. But it is not very 423ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// efficient, with calls to get and set values operating in linear time. 433ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// It has the additional limitation of having a fairly small fixed capacity of 443ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// SimpleStringDictionary::MAX_NUM_ENTRIES entries. An assert() will fire if 453ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// the client attempts to set more than this number of key/value pairs. 463ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Ordinarilly a C++ programmer would use something like the std::map template 473ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// class, or on the Macintosh would often choose CFDictionary or NSDictionary. 483ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// But these dictionary classes may call malloc() during get and set operations. 493ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// Google Breakpad requires that no memory allocations be made in code running 503ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// in its exception handling thread, so it uses SimpleStringDictionary as the 513ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// underlying implementation for the GoogleBreakpad.framework APIs: 523ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// GoogleBreakpadSetKeyValue(), GoogleBreakpadKeyValue(), and 533ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// GoogleBreakpadRemoveKeyValue() 543ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 553ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 563ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 573ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// KeyValueEntry 583ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 593ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// A helper class used by SimpleStringDictionary representing a single 603ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// storage cell for a key/value pair. Each key and value string are 613ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// limited to MAX_STRING_STORAGE_SIZE-1 bytes (not glyphs). This class 623ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// performs no memory allocations. It has methods for setting and getting 633ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// key and value strings. 643ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 653ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass KeyValueEntry { 663ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 673ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid KeyValueEntry() { 683ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid Clear(); 693ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 70303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org 713ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid KeyValueEntry(const char *key, const char *value) { 723ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid SetKeyValue(key, value); 733ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 743ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 75303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org void SetKeyValue(const char *key, const char *value) { 763ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid if (!key) { 773ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid key = ""; 783ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 793ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid if (!value) { 803ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid value = ""; 813ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 82303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org 833ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid strlcpy(key_, key, sizeof(key_)); 843ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid strlcpy(value_, value, sizeof(value_)); 85303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org } 863ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 87303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org void SetValue(const char *value) { 883ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid if (!value) { 893ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid value = ""; 903ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 913ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid strlcpy(value_, value, sizeof(value_)); 923ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid }; 93303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org 943ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Removes the key/value 95303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org void Clear() { 963ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid memset(key_, 0, sizeof(key_)); 973ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid memset(value_, 0, sizeof(value_)); 983ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 993ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 100303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org bool IsActive() const { return key_[0] != '\0'; } 1013ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid const char *GetKey() const { return key_; } 1023ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid const char *GetValue() const { return value_; } 1033ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1043ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Don't change this without considering the fixed size 1053ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // of MachMessage (in MachIPC.h) 1063ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // (see also struct KeyValueMessageData in Inspector.h) 1073ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid enum {MAX_STRING_STORAGE_SIZE = 256}; 108303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org 1093ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid private: 1103ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid char key_[MAX_STRING_STORAGE_SIZE]; 1113ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid char value_[MAX_STRING_STORAGE_SIZE]; 1123ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 1133ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1143ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 1153ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// This class is not an efficient dictionary, but for the purposes of breakpad 1163ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// will be just fine. We're just dealing with ten or so distinct 1173ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// key/value pairs. The idea is to avoid any malloc() or free() calls 1183ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// in certain important methods to be called when a process is in a 1193ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// crashed state. Each key and value string are limited to 1203ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// KeyValueEntry::MAX_STRING_STORAGE_SIZE-1 bytes (not glyphs). Strings passed 1213ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// in exceeding this length will be truncated. 1223ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid// 1233ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass SimpleStringDictionary { 1243ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 1253ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid SimpleStringDictionary() {}; // entries will all be cleared 126303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org 1273ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Returns the number of active key/value pairs. The upper limit for this 1283ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // is MAX_NUM_ENTRIES. 1293ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid int GetCount() const; 1303ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1313ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Given |key|, returns its corresponding |value|. 1323ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // If |key| is NULL, an assert will fire or NULL will be returned. If |key| 1333ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // is not found or is an empty string, NULL is returned. 13400936cf4ad413ec012b81c814319467c206d7447qsr@chromium.org const char *GetValueForKey(const char *key) const; 135303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org 1363ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Stores a string |value| represented by |key|. If |key| is NULL or an empty 1373ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // string, this will assert (or do nothing). If |value| is NULL then 1383ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // the |key| will be removed. An empty string is OK for |value|. 1393ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid void SetKeyValue(const char *key, const char *value); 140303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org 1413ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Given |key|, removes any associated value. It will assert (or do nothing) 1423ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // if NULL is passed in. It will do nothing if |key| is not found. 1433ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid void RemoveKey(const char *key); 1443ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1453ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // This is the maximum number of key/value pairs which may be set in the 1463ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // dictionary. An assert may fire if more values than this are set. 1473ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Don't change this without also changing comment in GoogleBreakpad.h 1483ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid enum {MAX_NUM_ENTRIES = 64}; 1493ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1503ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid private: 1513ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid friend class SimpleStringDictionaryIterator; 1523ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1533ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid const KeyValueEntry *GetEntry(int i) const; 1543ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 155303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org KeyValueEntry entries_[MAX_NUM_ENTRIES]; 1563ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 1573ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1583ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid//============================================================================== 1593ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsidclass SimpleStringDictionaryIterator { 1603ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid public: 1613ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid SimpleStringDictionaryIterator(const SimpleStringDictionary &dict) 1623ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid : dict_(dict), i_(0) { 1633ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1643ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1653ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // Initializes iterator to the beginning (may later call Next() ) 1663ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid void Start() { 1673ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid i_ = 0; 1683ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 169303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org 1703ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // like the nextObject method of NSEnumerator (in Cocoa) 1713ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // returns NULL when there are no more entries 1723ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid // 1733ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid const KeyValueEntry* Next() { 1743ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid for (; i_ < SimpleStringDictionary::MAX_NUM_ENTRIES; ++i_) { 1753ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid const KeyValueEntry *entry = dict_.GetEntry(i_); 1763ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid if (entry->IsActive()) { 1773ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid i_++; // move to next entry for next time 1783ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid return entry; 1793ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1803ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 1813ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1823ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid return NULL; // reached end of array 1833ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid } 184303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org 1853ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid private: 186303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org const SimpleStringDictionary& dict_; 187303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org int i_; 1883ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid}; 1893ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 1903ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid} // namespace google_breakpad 1913ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid 192303311b8370b307ea38201fc3ad241a5610f8cfcrsesek@chromium.org#endif // COMMON_SIMPLE_STRING_DICTIONARY_H_ 193