Page Speed Optimization Libraries
1.5.27.2
|
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_