PageRenderTime 29ms CodeModel.GetById 17ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/breakpad/common/mac/SimpleStringDictionary.h

http://github.com/tomahawk-player/tomahawk
C++ Header | 195 lines | 78 code | 29 blank | 88 comment | 6 complexity | a1c713a7860b85b73d3944b612f250d1 MD5 | raw file
  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
 39namespace 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//
 68class 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//
126class 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) const;
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//==============================================================================
162class 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__