Page Speed Optimization Libraries  1.5.27.2
net/instaweb/util/public/string_multi_map.h
Go to the documentation of this file.
00001 // Copyright 2010 Google Inc.
00016 
00017 #ifndef NET_INSTAWEB_UTIL_PUBLIC_STRING_MULTI_MAP_H_
00018 #define NET_INSTAWEB_UTIL_PUBLIC_STRING_MULTI_MAP_H_
00019 
00020 #include <map>
00021 #include <utility>
00022 #include <vector>
00023 #include "net/instaweb/util/public/basictypes.h"
00024 #include "net/instaweb/util/public/string.h"
00025 #include "net/instaweb/util/public/string_util.h"
00026 
00027 namespace net_instaweb {
00028 
00032 template<class StringCompare> class StringMultiMap {
00033  public:
00034   StringMultiMap() { }
00035   ~StringMultiMap() {
00036     Clear();
00037   }
00038 
00039   bool empty() {
00040     return vector_.empty();
00041   }
00042 
00043   void Clear() {
00044     for (int i = 0, n = vector_.size(); i < n; ++i) {
00045       delete vector_[i].second;
00046     }
00047     map_.clear();
00048     vector_.clear();
00049   }
00050 
00052   int num_names() const { return map_.size(); }
00053 
00056   int num_values() const { return vector_.size(); }
00057 
00062   bool Lookup(const StringPiece& name, ConstStringStarVector* values) const {
00063     typename Map::const_iterator p = map_.find(name.as_string());
00064     bool ret = false;
00065     if (p != map_.end()) {
00066       ret = true;
00067       *values = p->second;
00068     }
00069     return ret;
00070   }
00071 
00074   const GoogleString* Lookup1(const StringPiece& name) const {
00075     ConstStringStarVector v;
00076     if (Lookup(name, &v) && v.size() == 1) {
00077       return v[0];
00078     }
00079     return NULL;
00080   }
00081 
00082   bool Has(const StringPiece& name) const {
00083     return map_.find(name.as_string()) != map_.end();
00084   }
00085 
00087   bool RemoveAll(const StringPiece& var_name) {
00088     GoogleString var_string(var_name.data(), var_name.size());
00089     typename Map::iterator p = map_.find(var_string);
00090     bool removed = (p != map_.end());
00091     if (removed) {
00092       StringPairVector temp_vector; 
00093       temp_vector.reserve(vector_.size());
00094       for (int i = 0; i < num_values(); ++i) {
00095         if (!StringCaseEqual(name(i),  var_string)) {
00096           temp_vector.push_back(vector_[i]);
00097         } else {
00098           removed = true;
00099           delete vector_[i].second;
00100         }
00101       }
00102 
00103       vector_.swap(temp_vector);
00104 
00106       map_.erase(p);
00107     }
00108     return removed;
00109   }
00110 
00111   const char* name(int index) const { return vector_[index].first; }
00112 
00114   const GoogleString* value(int index) const { return vector_[index].second; }
00115 
00117   void Add(const StringPiece& var_name, const StringPiece& value) {
00118     ConstStringStarVector dummy_values;
00119     GoogleString name_buf(var_name.data(), var_name.size());
00120     std::pair<typename Map::iterator, bool> iter_inserted = map_.insert(
00121         typename Map::value_type(name_buf, dummy_values));
00122     typename Map::iterator iter = iter_inserted.first;
00123     ConstStringStarVector& values = iter->second;
00124     GoogleString* value_copy = NULL;
00125     if (value.data() != NULL) {
00126       value_copy = new GoogleString(value.as_string());
00127     }
00128     values.push_back(value_copy);
00129     vector_.push_back(StringPair(iter->first.c_str(), value_copy));
00130   }
00131 
00138   void AddFromNameValuePairs(const StringPiece& name_value_list,
00139                              const StringPiece& separators,
00140                              char value_separator,
00141                              bool omit_if_no_value) {
00142     StringPieceVector pairs;
00143     SplitStringPieceToVector(name_value_list, separators, &pairs, true);
00144     for (int i = 0, n = pairs.size(); i < n; ++i) {
00145       StringPiece& pair = pairs[i];
00146       StringPiece::size_type pos = pair.find(value_separator);
00147       if (pos != StringPiece::npos) {
00148         Add(pair.substr(0, pos), pair.substr(pos + 1));
00149       } else if (!omit_if_no_value) {
00150         Add(pair, StringPiece(NULL, 0));
00151       }
00152     }
00153   }
00154 
00155   void CopyFrom(const StringMultiMap& string_multi_map) {
00156     Clear();
00157     for (int i = 0; i < string_multi_map.num_values(); ++i) {
00158       const GoogleString* value = string_multi_map.value(i);
00159       if (value != NULL) {
00160         Add(string_multi_map.name(i), *value);
00161       } else {
00162         Add(string_multi_map.name(i), NULL);
00163       }
00164     }
00165   }
00166 
00167  private:
00176   typedef std::pair<const char*, GoogleString*> StringPair; 
00177   typedef std::map<GoogleString, ConstStringStarVector, StringCompare> Map;
00178   typedef std::vector<StringPair> StringPairVector;
00179 
00180   Map map_;
00181   StringPairVector vector_;
00182 
00183   DISALLOW_COPY_AND_ASSIGN(StringMultiMap);
00184 };
00185 
00186 class StringMultiMapInsensitive
00187     : public StringMultiMap<StringCompareInsensitive> {
00188  public:
00189   StringMultiMapInsensitive() { }
00190  private:
00191   DISALLOW_COPY_AND_ASSIGN(StringMultiMapInsensitive);
00192 };
00193 
00194 class StringMultiMapSensitive : public StringMultiMap<StringCompareSensitive> {
00195  public:
00196   StringMultiMapSensitive() { }
00197  private:
00198   DISALLOW_COPY_AND_ASSIGN(StringMultiMapSensitive);
00199 };
00200 
00201 }  
00202 
00203 #endif  ///< NET_INSTAWEB_UTIL_PUBLIC_STRING_MULTI_MAP_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines