toolkit/crashreporter/google-breakpad/src/common/unique_string.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 // Copyright (c) 2013 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.
    30 #ifndef COMMON_UNIQUE_STRING_H_
    31 #define COMMON_UNIQUE_STRING_H_
    33 #include <map>
    34 #include <string>
    35 #include "common/using_std_string.h"
    37 namespace google_breakpad {
    39 // Abstract type
    40 class UniqueString;
    42 // Unique-ify a string.  |ToUniqueString| can never return NULL.
    43 const UniqueString* ToUniqueString(string);
    45 // ditto, starting instead from the first n characters of a C string
    46 const UniqueString* ToUniqueString_n(const char* str, size_t n);
    48 // Pull chars out of the string.  No range checking.
    49 const char Index(const UniqueString*, int);
    51 // Get the contained C string (debugging only)
    52 const char* const FromUniqueString(const UniqueString*);
    54 // Do a strcmp-style comparison on the contained C string
    55 int StrcmpUniqueString(const UniqueString*, const UniqueString*);
    57 // Less-than comparison of two UniqueStrings, usable for std::sort.
    58 bool LessThan_UniqueString(const UniqueString*, const UniqueString*);
    60 // Some handy pre-uniqified strings.  Z is an escape character:
    61 //   ZS        '$'
    62 //   ZD        '.'
    63 //   Zeq       '='
    64 //   Zplus     '+'
    65 //   Zstar     '*'
    66 //   Zslash    '/'
    67 //   Zpercent  '%'
    68 //   Zat       '@'
    69 //   Zcaret    '^'
    71 // Note that ustr__empty and (UniqueString*)NULL are considered
    72 // to be different.
    73 //
    74 // Unfortunately these have to be written as functions so as to
    75 // make them safe to use in static initialisers.
    77 // ""
    78 inline static const UniqueString* ustr__empty() {
    79   static const UniqueString* us = NULL;
    80   if (!us) us = ToUniqueString("");
    81   return us;
    82 }
    84 // "$eip"
    85 inline static const UniqueString* ustr__ZSeip() {
    86   static const UniqueString* us = NULL;
    87   if (!us) us = ToUniqueString("$eip");
    88   return us;
    89 }
    91 // "$ebp"
    92 inline static const UniqueString* ustr__ZSebp() {
    93   static const UniqueString* us = NULL;
    94   if (!us) us = ToUniqueString("$ebp");
    95   return us;
    96 }
    98 // "$esp"
    99 inline static const UniqueString* ustr__ZSesp() {
   100   static const UniqueString* us = NULL;
   101   if (!us) us = ToUniqueString("$esp");
   102   return us;
   103 }
   105 // "$ebx"
   106 inline static const UniqueString* ustr__ZSebx() {
   107   static const UniqueString* us = NULL;
   108   if (!us) us = ToUniqueString("$ebx");
   109   return us;
   110 }
   112 // "$esi"
   113 inline static const UniqueString* ustr__ZSesi() {
   114   static const UniqueString* us = NULL;
   115   if (!us) us = ToUniqueString("$esi");
   116   return us;
   117 }
   119 // "$edi"
   120 inline static const UniqueString* ustr__ZSedi() {
   121   static const UniqueString* us = NULL;
   122   if (!us) us = ToUniqueString("$edi");
   123   return us;
   124 }
   126 // ".cbCalleeParams"
   127 inline static const UniqueString* ustr__ZDcbCalleeParams() {
   128   static const UniqueString* us = NULL;
   129   if (!us) us = ToUniqueString(".cbCalleeParams");
   130   return us;
   131 }
   133 // ".cbSavedRegs"
   134 inline static const UniqueString* ustr__ZDcbSavedRegs() {
   135   static const UniqueString* us = NULL;
   136   if (!us) us = ToUniqueString(".cbSavedRegs");
   137   return us;
   138 }
   140 // ".cbLocals"
   141 inline static const UniqueString* ustr__ZDcbLocals() {
   142   static const UniqueString* us = NULL;
   143   if (!us) us = ToUniqueString(".cbLocals");
   144   return us;
   145 }
   147 // ".raSearchStart"
   148 inline static const UniqueString* ustr__ZDraSearchStart() {
   149   static const UniqueString* us = NULL;
   150   if (!us) us = ToUniqueString(".raSearchStart");
   151   return us;
   152 }
   154 // ".raSearch"
   155 inline static const UniqueString* ustr__ZDraSearch() {
   156   static const UniqueString* us = NULL;
   157   if (!us) us = ToUniqueString(".raSearch");
   158   return us;
   159 }
   161 // ".cbParams"
   162 inline static const UniqueString* ustr__ZDcbParams() {
   163   static const UniqueString* us = NULL;
   164   if (!us) us = ToUniqueString(".cbParams");
   165   return us;
   166 }
   168 // "+"
   169 inline static const UniqueString* ustr__Zplus() {
   170   static const UniqueString* us = NULL;
   171   if (!us) us = ToUniqueString("+");
   172   return us;
   173 }
   175 // "-"
   176 inline static const UniqueString* ustr__Zminus() {
   177   static const UniqueString* us = NULL;
   178   if (!us) us = ToUniqueString("-");
   179   return us;
   180 }
   182 // "*"
   183 inline static const UniqueString* ustr__Zstar() {
   184   static const UniqueString* us = NULL;
   185   if (!us) us = ToUniqueString("*");
   186   return us;
   187 }
   189 // "/"
   190 inline static const UniqueString* ustr__Zslash() {
   191   static const UniqueString* us = NULL;
   192   if (!us) us = ToUniqueString("/");
   193   return us;
   194 }
   196 // "%"
   197 inline static const UniqueString* ustr__Zpercent() {
   198   static const UniqueString* us = NULL;
   199   if (!us) us = ToUniqueString("%");
   200   return us;
   201 }
   203 // "@"
   204 inline static const UniqueString* ustr__Zat() {
   205   static const UniqueString* us = NULL;
   206   if (!us) us = ToUniqueString("@");
   207   return us;
   208 }
   210 // "^"
   211 inline static const UniqueString* ustr__Zcaret() {
   212   static const UniqueString* us = NULL;
   213   if (!us) us = ToUniqueString("^");
   214   return us;
   215 }
   217 // "="
   218 inline static const UniqueString* ustr__Zeq() {
   219   static const UniqueString* us = NULL;
   220   if (!us) us = ToUniqueString("=");
   221   return us;
   222 }
   224 // ".cfa"
   225 inline static const UniqueString* ustr__ZDcfa() {
   226   static const UniqueString* us = NULL;
   227   if (!us) us = ToUniqueString(".cfa");
   228   return us;
   229 }
   231 // ".ra"
   232 inline static const UniqueString* ustr__ZDra() {
   233   static const UniqueString* us = NULL;
   234   if (!us) us = ToUniqueString(".ra");
   235   return us;
   236 }
   238 // "pc"
   239 inline static const UniqueString* ustr__pc() {
   240   static const UniqueString* us = NULL;
   241   if (!us) us = ToUniqueString("pc");
   242   return us;
   243 }
   245 // "lr"
   246 inline static const UniqueString* ustr__lr() {
   247   static const UniqueString* us = NULL;
   248   if (!us) us = ToUniqueString("lr");
   249   return us;
   250 }
   252 // "sp"
   253 inline static const UniqueString* ustr__sp() {
   254   static const UniqueString* us = NULL;
   255   if (!us) us = ToUniqueString("sp");
   256   return us;
   257 }
   259 template <typename ValueType>
   260 class UniqueStringMap
   261 {
   262  private:
   263   static const int N_FIXED = 10;
   265  public:
   266   UniqueStringMap() : n_fixed_(0), n_sets_(0), n_gets_(0), n_clears_(0) {};
   267   ~UniqueStringMap() {};
   269   // Empty out the map.
   270   void clear() {
   271     ++n_clears_;
   272     map_.clear();
   273     n_fixed_ = 0;
   274   }
   276   // Do "map[ix] = v".
   277   void set(const UniqueString* ix, ValueType v) {
   278     ++n_sets_;
   279     int i;
   280     for (i = 0; i < n_fixed_; ++i) {
   281       if (fixed_keys_[i] == ix) {
   282         fixed_vals_[i] = v;
   283         return;
   284       }
   285     }
   286     if (n_fixed_ < N_FIXED) {
   287       i = n_fixed_;
   288       fixed_keys_[i] = ix;
   289       fixed_vals_[i] = v;
   290       ++n_fixed_;
   291     } else {
   292       map_[ix] = v;
   293     }
   294   }
   296   // Lookup 'ix' in the map, and also return a success/fail boolean.
   297   ValueType get(/*OUT*/bool* have, const UniqueString* ix) const {
   298     ++n_gets_;
   299     int i;
   300     for (i = 0; i < n_fixed_; ++i) {
   301       if (fixed_keys_[i] == ix) {
   302         *have = true;
   303         return fixed_vals_[i];
   304       }
   305     }
   306     typename std::map<const UniqueString*, ValueType>::const_iterator it
   307         = map_.find(ix);
   308     if (it == map_.end()) {
   309       *have = false;
   310       return ValueType();
   311     } else {
   312       *have = true;
   313       return it->second;
   314     }
   315   };
   317   // Lookup 'ix' in the map, and return zero if it is not present.
   318   ValueType get(const UniqueString* ix) const {
   319     ++n_gets_;
   320     bool found;
   321     ValueType v = get(&found, ix);
   322     return found ? v : ValueType();
   323   }
   325   // Find out whether 'ix' is in the map.
   326   bool have(const UniqueString* ix) const {
   327     ++n_gets_;
   328     bool found;
   329     (void)get(&found, ix);
   330     return found;
   331   }
   333   // Copy the contents to a std::map, generally for testing.
   334   void copy_to_map(std::map<const UniqueString*, ValueType>* m) const {
   335     m->clear();
   336     int i;
   337     for (i = 0; i < n_fixed_; ++i) {
   338       (*m)[fixed_keys_[i]] = fixed_vals_[i];
   339     }
   340     m->insert(map_.begin(), map_.end());
   341   }
   343   // Note that users of this class rely on having also a sane
   344   // assignment operator.  The default one is OK, though.
   345   // AFAICT there are no uses of the copy constructor, but if
   346   // there were, the default one would also suffice.
   348  private:
   349   // Quick (hopefully) cache
   350   const UniqueString* fixed_keys_[N_FIXED];
   351   ValueType           fixed_vals_[N_FIXED];
   352   int                 n_fixed_;  // 0 .. N_FIXED inclusive
   353   // Fallback storage when the cache is filled
   354   std::map<const UniqueString*, ValueType> map_;
   356   // For tracking usage stats.
   357   mutable int n_sets_, n_gets_, n_clears_;
   358 };
   360 }  // namespace google_breakpad
   362 #endif  // COMMON_UNIQUE_STRING_H_

mercurial