/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. #ifndef SimpleStringDictionary_H__
  33. #define SimpleStringDictionary_H__
  34. #import <string>
  35. #import <vector>
  36. namespace google_breakpad {
  37. //==============================================================================
  38. // SimpleStringDictionary (and associated class KeyValueEntry) implement a very
  39. // basic dictionary container class. It has the property of not making any
  40. // memory allocations when getting and setting values. But it is not very
  41. // efficient, with calls to get and set values operating in linear time.
  42. // It has the additional limitation of having a fairly small fixed capacity of
  43. // SimpleStringDictionary::MAX_NUM_ENTRIES entries. An assert() will fire if
  44. // the client attempts to set more than this number of key/value pairs.
  45. // Ordinarilly a C++ programmer would use something like the std::map template
  46. // class, or on the Macintosh would often choose CFDictionary or NSDictionary.
  47. // But these dictionary classes may call malloc() during get and set operations.
  48. // Google Breakpad requires that no memory allocations be made in code running
  49. // in its exception handling thread, so it uses SimpleStringDictionary as the
  50. // underlying implementation for the GoogleBreakpad.framework APIs:
  51. // GoogleBreakpadSetKeyValue(), GoogleBreakpadKeyValue(), and
  52. // GoogleBreakpadRemoveKeyValue()
  53. //
  54. //==============================================================================
  55. // KeyValueEntry
  56. //
  57. // A helper class used by SimpleStringDictionary representing a single
  58. // storage cell for a key/value pair. Each key and value string are
  59. // limited to MAX_STRING_STORAGE_SIZE-1 bytes (not glyphs). This class
  60. // performs no memory allocations. It has methods for setting and getting
  61. // key and value strings.
  62. //
  63. class KeyValueEntry {
  64. public:
  65. KeyValueEntry() {
  66. Clear();
  67. }
  68. KeyValueEntry(const char *key, const char *value) {
  69. SetKeyValue(key, value);
  70. }
  71. void SetKeyValue(const char *key, const char *value) {
  72. if (!key) {
  73. key = "";
  74. }
  75. if (!value) {
  76. value = "";
  77. }
  78. strlcpy(key_, key, sizeof(key_));
  79. strlcpy(value_, value, sizeof(value_));
  80. }
  81. void SetValue(const char *value) {
  82. if (!value) {
  83. value = "";
  84. }
  85. strlcpy(value_, value, sizeof(value_));
  86. };
  87. // Removes the key/value
  88. void Clear() {
  89. memset(key_, 0, sizeof(key_));
  90. memset(value_, 0, sizeof(value_));
  91. }
  92. bool IsActive() const { return key_[0] != '\0'; }
  93. const char *GetKey() const { return key_; }
  94. const char *GetValue() const { return value_; }
  95. // Don't change this without considering the fixed size
  96. // of MachMessage (in MachIPC.h)
  97. // (see also struct KeyValueMessageData in Inspector.h)
  98. enum {MAX_STRING_STORAGE_SIZE = 256};
  99. private:
  100. char key_[MAX_STRING_STORAGE_SIZE];
  101. char value_[MAX_STRING_STORAGE_SIZE];
  102. };
  103. //==============================================================================
  104. // This class is not an efficient dictionary, but for the purposes of breakpad
  105. // will be just fine. We're just dealing with ten or so distinct
  106. // key/value pairs. The idea is to avoid any malloc() or free() calls
  107. // in certain important methods to be called when a process is in a
  108. // crashed state. Each key and value string are limited to
  109. // KeyValueEntry::MAX_STRING_STORAGE_SIZE-1 bytes (not glyphs). Strings passed
  110. // in exceeding this length will be truncated.
  111. //
  112. class SimpleStringDictionary {
  113. public:
  114. SimpleStringDictionary() {}; // entries will all be cleared
  115. // Returns the number of active key/value pairs. The upper limit for this
  116. // is MAX_NUM_ENTRIES.
  117. int GetCount() const;
  118. // Given |key|, returns its corresponding |value|.
  119. // If |key| is NULL, an assert will fire or NULL will be returned. If |key|
  120. // is not found or is an empty string, NULL is returned.
  121. const char *GetValueForKey(const char *key) const;
  122. // Stores a string |value| represented by |key|. If |key| is NULL or an empty
  123. // string, this will assert (or do nothing). If |value| is NULL then
  124. // the |key| will be removed. An empty string is OK for |value|.
  125. void SetKeyValue(const char *key, const char *value);
  126. // Given |key|, removes any associated value. It will assert (or do nothing)
  127. // if NULL is passed in. It will do nothing if |key| is not found.
  128. void RemoveKey(const char *key);
  129. // This is the maximum number of key/value pairs which may be set in the
  130. // dictionary. An assert may fire if more values than this are set.
  131. // Don't change this without also changing comment in GoogleBreakpad.h
  132. enum {MAX_NUM_ENTRIES = 64};
  133. private:
  134. friend class SimpleStringDictionaryIterator;
  135. const KeyValueEntry *GetEntry(int i) const;
  136. KeyValueEntry entries_[MAX_NUM_ENTRIES];
  137. };
  138. //==============================================================================
  139. class SimpleStringDictionaryIterator {
  140. public:
  141. SimpleStringDictionaryIterator(const SimpleStringDictionary &dict)
  142. : dict_(dict), i_(0) {
  143. }
  144. // Initializes iterator to the beginning (may later call Next() )
  145. void Start() {
  146. i_ = 0;
  147. }
  148. // like the nextObject method of NSEnumerator (in Cocoa)
  149. // returns NULL when there are no more entries
  150. //
  151. const KeyValueEntry* Next() {
  152. for (; i_ < SimpleStringDictionary::MAX_NUM_ENTRIES; ++i_) {
  153. const KeyValueEntry *entry = dict_.GetEntry(i_);
  154. if (entry->IsActive()) {
  155. i_++; // move to next entry for next time
  156. return entry;
  157. }
  158. }
  159. return NULL; // reached end of array
  160. }
  161. private:
  162. const SimpleStringDictionary& dict_;
  163. int i_;
  164. };
  165. } // namespace google_breakpad
  166. #endif // SimpleStringDictionary_H__