1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/values.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,531 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +// This file specifies a recursive data storage class called Value intended for 1.9 +// storing settings and other persistable data. 1.10 +// 1.11 +// A Value represents something that can be stored in JSON or passed to/from 1.12 +// JavaScript. As such, it is NOT a generalized variant type, since only the 1.13 +// types supported by JavaScript/JSON are supported. 1.14 +// 1.15 +// IN PARTICULAR this means that there is no support for int64 or unsigned 1.16 +// numbers. Writing JSON with such types would violate the spec. If you need 1.17 +// something like this, either use a double or make a string value containing 1.18 +// the number you want. 1.19 + 1.20 +#ifndef BASE_VALUES_H_ 1.21 +#define BASE_VALUES_H_ 1.22 + 1.23 +#include <stddef.h> 1.24 + 1.25 +#include <iosfwd> 1.26 +#include <map> 1.27 +#include <string> 1.28 +#include <utility> 1.29 +#include <vector> 1.30 + 1.31 +#include "base/base_export.h" 1.32 +#include "base/basictypes.h" 1.33 +#include "base/compiler_specific.h" 1.34 +#include "base/memory/scoped_ptr.h" 1.35 +#include "base/strings/string16.h" 1.36 + 1.37 +// This file declares "using base::Value", etc. at the bottom, so that 1.38 +// current code can use these classes without the base namespace. In 1.39 +// new code, please always use base::Value, etc. or add your own 1.40 +// "using" declaration. 1.41 +// http://crbug.com/88666 1.42 +namespace base { 1.43 + 1.44 +class DictionaryValue; 1.45 +class FundamentalValue; 1.46 +class ListValue; 1.47 +class StringValue; 1.48 +class Value; 1.49 + 1.50 +typedef std::vector<Value*> ValueVector; 1.51 +typedef std::map<std::string, Value*> ValueMap; 1.52 + 1.53 +// The Value class is the base class for Values. A Value can be instantiated 1.54 +// via the Create*Value() factory methods, or by directly creating instances of 1.55 +// the subclasses. 1.56 +// 1.57 +// See the file-level comment above for more information. 1.58 +class BASE_EXPORT Value { 1.59 + public: 1.60 + enum Type { 1.61 + TYPE_NULL = 0, 1.62 + TYPE_BOOLEAN, 1.63 + TYPE_INTEGER, 1.64 + TYPE_DOUBLE, 1.65 + TYPE_STRING, 1.66 + TYPE_BINARY, 1.67 + TYPE_DICTIONARY, 1.68 + TYPE_LIST 1.69 + // Note: Do not add more types. See the file-level comment above for why. 1.70 + }; 1.71 + 1.72 + virtual ~Value(); 1.73 + 1.74 + static Value* CreateNullValue(); 1.75 + // DEPRECATED: Do not use the following 5 functions. Instead, use 1.76 + // new FundamentalValue or new StringValue. 1.77 + static FundamentalValue* CreateBooleanValue(bool in_value); 1.78 + static FundamentalValue* CreateIntegerValue(int in_value); 1.79 + static FundamentalValue* CreateDoubleValue(double in_value); 1.80 + static StringValue* CreateStringValue(const std::string& in_value); 1.81 + static StringValue* CreateStringValue(const string16& in_value); 1.82 + 1.83 + // Returns the type of the value stored by the current Value object. 1.84 + // Each type will be implemented by only one subclass of Value, so it's 1.85 + // safe to use the Type to determine whether you can cast from 1.86 + // Value* to (Implementing Class)*. Also, a Value object never changes 1.87 + // its type after construction. 1.88 + Type GetType() const { return type_; } 1.89 + 1.90 + // Returns true if the current object represents a given type. 1.91 + bool IsType(Type type) const { return type == type_; } 1.92 + 1.93 + // These methods allow the convenient retrieval of the contents of the Value. 1.94 + // If the current object can be converted into the given type, the value is 1.95 + // returned through the |out_value| parameter and true is returned; 1.96 + // otherwise, false is returned and |out_value| is unchanged. 1.97 + virtual bool GetAsBoolean(bool* out_value) const; 1.98 + virtual bool GetAsInteger(int* out_value) const; 1.99 + virtual bool GetAsDouble(double* out_value) const; 1.100 + virtual bool GetAsString(std::string* out_value) const; 1.101 + virtual bool GetAsString(string16* out_value) const; 1.102 + virtual bool GetAsList(ListValue** out_value); 1.103 + virtual bool GetAsList(const ListValue** out_value) const; 1.104 + virtual bool GetAsDictionary(DictionaryValue** out_value); 1.105 + virtual bool GetAsDictionary(const DictionaryValue** out_value) const; 1.106 + // Note: Do not add more types. See the file-level comment above for why. 1.107 + 1.108 + // This creates a deep copy of the entire Value tree, and returns a pointer 1.109 + // to the copy. The caller gets ownership of the copy, of course. 1.110 + // 1.111 + // Subclasses return their own type directly in their overrides; 1.112 + // this works because C++ supports covariant return types. 1.113 + virtual Value* DeepCopy() const; 1.114 + 1.115 + // Compares if two Value objects have equal contents. 1.116 + virtual bool Equals(const Value* other) const; 1.117 + 1.118 + // Compares if two Value objects have equal contents. Can handle NULLs. 1.119 + // NULLs are considered equal but different from Value::CreateNullValue(). 1.120 + static bool Equals(const Value* a, const Value* b); 1.121 + 1.122 + protected: 1.123 + // These aren't safe for end-users, but they are useful for subclasses. 1.124 + explicit Value(Type type); 1.125 + Value(const Value& that); 1.126 + Value& operator=(const Value& that); 1.127 + 1.128 + private: 1.129 + Type type_; 1.130 +}; 1.131 + 1.132 +// FundamentalValue represents the simple fundamental types of values. 1.133 +class BASE_EXPORT FundamentalValue : public Value { 1.134 + public: 1.135 + explicit FundamentalValue(bool in_value); 1.136 + explicit FundamentalValue(int in_value); 1.137 + explicit FundamentalValue(double in_value); 1.138 + virtual ~FundamentalValue(); 1.139 + 1.140 + // Overridden from Value: 1.141 + virtual bool GetAsBoolean(bool* out_value) const OVERRIDE; 1.142 + virtual bool GetAsInteger(int* out_value) const OVERRIDE; 1.143 + virtual bool GetAsDouble(double* out_value) const OVERRIDE; 1.144 + virtual FundamentalValue* DeepCopy() const OVERRIDE; 1.145 + virtual bool Equals(const Value* other) const OVERRIDE; 1.146 + 1.147 + private: 1.148 + union { 1.149 + bool boolean_value_; 1.150 + int integer_value_; 1.151 + double double_value_; 1.152 + }; 1.153 +}; 1.154 + 1.155 +class BASE_EXPORT StringValue : public Value { 1.156 + public: 1.157 + // Initializes a StringValue with a UTF-8 narrow character string. 1.158 + explicit StringValue(const std::string& in_value); 1.159 + 1.160 + // Initializes a StringValue with a string16. 1.161 + explicit StringValue(const string16& in_value); 1.162 + 1.163 + virtual ~StringValue(); 1.164 + 1.165 + // Overridden from Value: 1.166 + virtual bool GetAsString(std::string* out_value) const OVERRIDE; 1.167 + virtual bool GetAsString(string16* out_value) const OVERRIDE; 1.168 + virtual StringValue* DeepCopy() const OVERRIDE; 1.169 + virtual bool Equals(const Value* other) const OVERRIDE; 1.170 + 1.171 + private: 1.172 + std::string value_; 1.173 +}; 1.174 + 1.175 +class BASE_EXPORT BinaryValue: public Value { 1.176 + public: 1.177 + // Creates a BinaryValue with a null buffer and size of 0. 1.178 + BinaryValue(); 1.179 + 1.180 + // Creates a BinaryValue, taking ownership of the bytes pointed to by 1.181 + // |buffer|. 1.182 + BinaryValue(scoped_ptr<char[]> buffer, size_t size); 1.183 + 1.184 + virtual ~BinaryValue(); 1.185 + 1.186 + // For situations where you want to keep ownership of your buffer, this 1.187 + // factory method creates a new BinaryValue by copying the contents of the 1.188 + // buffer that's passed in. 1.189 + static BinaryValue* CreateWithCopiedBuffer(const char* buffer, size_t size); 1.190 + 1.191 + size_t GetSize() const { return size_; } 1.192 + 1.193 + // May return NULL. 1.194 + char* GetBuffer() { return buffer_.get(); } 1.195 + const char* GetBuffer() const { return buffer_.get(); } 1.196 + 1.197 + // Overridden from Value: 1.198 + virtual BinaryValue* DeepCopy() const OVERRIDE; 1.199 + virtual bool Equals(const Value* other) const OVERRIDE; 1.200 + 1.201 + private: 1.202 + scoped_ptr<char[]> buffer_; 1.203 + size_t size_; 1.204 + 1.205 + DISALLOW_COPY_AND_ASSIGN(BinaryValue); 1.206 +}; 1.207 + 1.208 +// DictionaryValue provides a key-value dictionary with (optional) "path" 1.209 +// parsing for recursive access; see the comment at the top of the file. Keys 1.210 +// are |std::string|s and should be UTF-8 encoded. 1.211 +class BASE_EXPORT DictionaryValue : public Value { 1.212 + public: 1.213 + DictionaryValue(); 1.214 + virtual ~DictionaryValue(); 1.215 + 1.216 + // Overridden from Value: 1.217 + virtual bool GetAsDictionary(DictionaryValue** out_value) OVERRIDE; 1.218 + virtual bool GetAsDictionary( 1.219 + const DictionaryValue** out_value) const OVERRIDE; 1.220 + 1.221 + // Returns true if the current dictionary has a value for the given key. 1.222 + bool HasKey(const std::string& key) const; 1.223 + 1.224 + // Returns the number of Values in this dictionary. 1.225 + size_t size() const { return dictionary_.size(); } 1.226 + 1.227 + // Returns whether the dictionary is empty. 1.228 + bool empty() const { return dictionary_.empty(); } 1.229 + 1.230 + // Clears any current contents of this dictionary. 1.231 + void Clear(); 1.232 + 1.233 + // Sets the Value associated with the given path starting from this object. 1.234 + // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes 1.235 + // into the next DictionaryValue down. Obviously, "." can't be used 1.236 + // within a key, but there are no other restrictions on keys. 1.237 + // If the key at any step of the way doesn't exist, or exists but isn't 1.238 + // a DictionaryValue, a new DictionaryValue will be created and attached 1.239 + // to the path in that location. 1.240 + // Note that the dictionary takes ownership of the value referenced by 1.241 + // |in_value|, and therefore |in_value| must be non-NULL. 1.242 + void Set(const std::string& path, Value* in_value); 1.243 + 1.244 + // Convenience forms of Set(). These methods will replace any existing 1.245 + // value at that path, even if it has a different type. 1.246 + void SetBoolean(const std::string& path, bool in_value); 1.247 + void SetInteger(const std::string& path, int in_value); 1.248 + void SetDouble(const std::string& path, double in_value); 1.249 + void SetString(const std::string& path, const std::string& in_value); 1.250 + void SetString(const std::string& path, const string16& in_value); 1.251 + 1.252 + // Like Set(), but without special treatment of '.'. This allows e.g. URLs to 1.253 + // be used as paths. 1.254 + void SetWithoutPathExpansion(const std::string& key, Value* in_value); 1.255 + 1.256 + // Convenience forms of SetWithoutPathExpansion(). 1.257 + void SetBooleanWithoutPathExpansion(const std::string& path, bool in_value); 1.258 + void SetIntegerWithoutPathExpansion(const std::string& path, int in_value); 1.259 + void SetDoubleWithoutPathExpansion(const std::string& path, double in_value); 1.260 + void SetStringWithoutPathExpansion(const std::string& path, 1.261 + const std::string& in_value); 1.262 + void SetStringWithoutPathExpansion(const std::string& path, 1.263 + const string16& in_value); 1.264 + 1.265 + // Gets the Value associated with the given path starting from this object. 1.266 + // A path has the form "<key>" or "<key>.<key>.[...]", where "." indexes 1.267 + // into the next DictionaryValue down. If the path can be resolved 1.268 + // successfully, the value for the last key in the path will be returned 1.269 + // through the |out_value| parameter, and the function will return true. 1.270 + // Otherwise, it will return false and |out_value| will be untouched. 1.271 + // Note that the dictionary always owns the value that's returned. 1.272 + bool Get(const std::string& path, const Value** out_value) const; 1.273 + bool Get(const std::string& path, Value** out_value); 1.274 + 1.275 + // These are convenience forms of Get(). The value will be retrieved 1.276 + // and the return value will be true if the path is valid and the value at 1.277 + // the end of the path can be returned in the form specified. 1.278 + bool GetBoolean(const std::string& path, bool* out_value) const; 1.279 + bool GetInteger(const std::string& path, int* out_value) const; 1.280 + bool GetDouble(const std::string& path, double* out_value) const; 1.281 + bool GetString(const std::string& path, std::string* out_value) const; 1.282 + bool GetString(const std::string& path, string16* out_value) const; 1.283 + bool GetStringASCII(const std::string& path, std::string* out_value) const; 1.284 + bool GetBinary(const std::string& path, const BinaryValue** out_value) const; 1.285 + bool GetBinary(const std::string& path, BinaryValue** out_value); 1.286 + bool GetDictionary(const std::string& path, 1.287 + const DictionaryValue** out_value) const; 1.288 + bool GetDictionary(const std::string& path, DictionaryValue** out_value); 1.289 + bool GetList(const std::string& path, const ListValue** out_value) const; 1.290 + bool GetList(const std::string& path, ListValue** out_value); 1.291 + 1.292 + // Like Get(), but without special treatment of '.'. This allows e.g. URLs to 1.293 + // be used as paths. 1.294 + bool GetWithoutPathExpansion(const std::string& key, 1.295 + const Value** out_value) const; 1.296 + bool GetWithoutPathExpansion(const std::string& key, Value** out_value); 1.297 + bool GetBooleanWithoutPathExpansion(const std::string& key, 1.298 + bool* out_value) const; 1.299 + bool GetIntegerWithoutPathExpansion(const std::string& key, 1.300 + int* out_value) const; 1.301 + bool GetDoubleWithoutPathExpansion(const std::string& key, 1.302 + double* out_value) const; 1.303 + bool GetStringWithoutPathExpansion(const std::string& key, 1.304 + std::string* out_value) const; 1.305 + bool GetStringWithoutPathExpansion(const std::string& key, 1.306 + string16* out_value) const; 1.307 + bool GetDictionaryWithoutPathExpansion( 1.308 + const std::string& key, 1.309 + const DictionaryValue** out_value) const; 1.310 + bool GetDictionaryWithoutPathExpansion(const std::string& key, 1.311 + DictionaryValue** out_value); 1.312 + bool GetListWithoutPathExpansion(const std::string& key, 1.313 + const ListValue** out_value) const; 1.314 + bool GetListWithoutPathExpansion(const std::string& key, 1.315 + ListValue** out_value); 1.316 + 1.317 + // Removes the Value with the specified path from this dictionary (or one 1.318 + // of its child dictionaries, if the path is more than just a local key). 1.319 + // If |out_value| is non-NULL, the removed Value will be passed out via 1.320 + // |out_value|. If |out_value| is NULL, the removed value will be deleted. 1.321 + // This method returns true if |path| is a valid path; otherwise it will 1.322 + // return false and the DictionaryValue object will be unchanged. 1.323 + virtual bool Remove(const std::string& path, scoped_ptr<Value>* out_value); 1.324 + 1.325 + // Like Remove(), but without special treatment of '.'. This allows e.g. URLs 1.326 + // to be used as paths. 1.327 + virtual bool RemoveWithoutPathExpansion(const std::string& key, 1.328 + scoped_ptr<Value>* out_value); 1.329 + 1.330 + // Makes a copy of |this| but doesn't include empty dictionaries and lists in 1.331 + // the copy. This never returns NULL, even if |this| itself is empty. 1.332 + DictionaryValue* DeepCopyWithoutEmptyChildren() const; 1.333 + 1.334 + // Merge |dictionary| into this dictionary. This is done recursively, i.e. any 1.335 + // sub-dictionaries will be merged as well. In case of key collisions, the 1.336 + // passed in dictionary takes precedence and data already present will be 1.337 + // replaced. Values within |dictionary| are deep-copied, so |dictionary| may 1.338 + // be freed any time after this call. 1.339 + void MergeDictionary(const DictionaryValue* dictionary); 1.340 + 1.341 + // Swaps contents with the |other| dictionary. 1.342 + virtual void Swap(DictionaryValue* other); 1.343 + 1.344 + // This class provides an iterator over both keys and values in the 1.345 + // dictionary. It can't be used to modify the dictionary. 1.346 + class BASE_EXPORT Iterator { 1.347 + public: 1.348 + explicit Iterator(const DictionaryValue& target); 1.349 + 1.350 + bool IsAtEnd() const { return it_ == target_.dictionary_.end(); } 1.351 + void Advance() { ++it_; } 1.352 + 1.353 + const std::string& key() const { return it_->first; } 1.354 + const Value& value() const { return *it_->second; } 1.355 + 1.356 + private: 1.357 + const DictionaryValue& target_; 1.358 + ValueMap::const_iterator it_; 1.359 + }; 1.360 + 1.361 + // Overridden from Value: 1.362 + virtual DictionaryValue* DeepCopy() const OVERRIDE; 1.363 + virtual bool Equals(const Value* other) const OVERRIDE; 1.364 + 1.365 + private: 1.366 + ValueMap dictionary_; 1.367 + 1.368 + DISALLOW_COPY_AND_ASSIGN(DictionaryValue); 1.369 +}; 1.370 + 1.371 +// This type of Value represents a list of other Value values. 1.372 +class BASE_EXPORT ListValue : public Value { 1.373 + public: 1.374 + typedef ValueVector::iterator iterator; 1.375 + typedef ValueVector::const_iterator const_iterator; 1.376 + 1.377 + ListValue(); 1.378 + virtual ~ListValue(); 1.379 + 1.380 + // Clears the contents of this ListValue 1.381 + void Clear(); 1.382 + 1.383 + // Returns the number of Values in this list. 1.384 + size_t GetSize() const { return list_.size(); } 1.385 + 1.386 + // Returns whether the list is empty. 1.387 + bool empty() const { return list_.empty(); } 1.388 + 1.389 + // Sets the list item at the given index to be the Value specified by 1.390 + // the value given. If the index beyond the current end of the list, null 1.391 + // Values will be used to pad out the list. 1.392 + // Returns true if successful, or false if the index was negative or 1.393 + // the value is a null pointer. 1.394 + bool Set(size_t index, Value* in_value); 1.395 + 1.396 + // Gets the Value at the given index. Modifies |out_value| (and returns true) 1.397 + // only if the index falls within the current list range. 1.398 + // Note that the list always owns the Value passed out via |out_value|. 1.399 + bool Get(size_t index, const Value** out_value) const; 1.400 + bool Get(size_t index, Value** out_value); 1.401 + 1.402 + // Convenience forms of Get(). Modifies |out_value| (and returns true) 1.403 + // only if the index is valid and the Value at that index can be returned 1.404 + // in the specified form. 1.405 + bool GetBoolean(size_t index, bool* out_value) const; 1.406 + bool GetInteger(size_t index, int* out_value) const; 1.407 + bool GetDouble(size_t index, double* out_value) const; 1.408 + bool GetString(size_t index, std::string* out_value) const; 1.409 + bool GetString(size_t index, string16* out_value) const; 1.410 + bool GetBinary(size_t index, const BinaryValue** out_value) const; 1.411 + bool GetBinary(size_t index, BinaryValue** out_value); 1.412 + bool GetDictionary(size_t index, const DictionaryValue** out_value) const; 1.413 + bool GetDictionary(size_t index, DictionaryValue** out_value); 1.414 + bool GetList(size_t index, const ListValue** out_value) const; 1.415 + bool GetList(size_t index, ListValue** out_value); 1.416 + 1.417 + // Removes the Value with the specified index from this list. 1.418 + // If |out_value| is non-NULL, the removed Value AND ITS OWNERSHIP will be 1.419 + // passed out via |out_value|. If |out_value| is NULL, the removed value will 1.420 + // be deleted. This method returns true if |index| is valid; otherwise 1.421 + // it will return false and the ListValue object will be unchanged. 1.422 + virtual bool Remove(size_t index, scoped_ptr<Value>* out_value); 1.423 + 1.424 + // Removes the first instance of |value| found in the list, if any, and 1.425 + // deletes it. |index| is the location where |value| was found. Returns false 1.426 + // if not found. 1.427 + bool Remove(const Value& value, size_t* index); 1.428 + 1.429 + // Removes the element at |iter|. If |out_value| is NULL, the value will be 1.430 + // deleted, otherwise ownership of the value is passed back to the caller. 1.431 + // Returns an iterator pointing to the location of the element that 1.432 + // followed the erased element. 1.433 + iterator Erase(iterator iter, scoped_ptr<Value>* out_value); 1.434 + 1.435 + // Appends a Value to the end of the list. 1.436 + void Append(Value* in_value); 1.437 + 1.438 + // Convenience forms of Append. 1.439 + void AppendBoolean(bool in_value); 1.440 + void AppendInteger(int in_value); 1.441 + void AppendDouble(double in_value); 1.442 + void AppendString(const std::string& in_value); 1.443 + void AppendString(const string16& in_value); 1.444 + void AppendStrings(const std::vector<std::string>& in_values); 1.445 + void AppendStrings(const std::vector<string16>& in_values); 1.446 + 1.447 + // Appends a Value if it's not already present. Takes ownership of the 1.448 + // |in_value|. Returns true if successful, or false if the value was already 1.449 + // present. If the value was already present the |in_value| is deleted. 1.450 + bool AppendIfNotPresent(Value* in_value); 1.451 + 1.452 + // Insert a Value at index. 1.453 + // Returns true if successful, or false if the index was out of range. 1.454 + bool Insert(size_t index, Value* in_value); 1.455 + 1.456 + // Searches for the first instance of |value| in the list using the Equals 1.457 + // method of the Value type. 1.458 + // Returns a const_iterator to the found item or to end() if none exists. 1.459 + const_iterator Find(const Value& value) const; 1.460 + 1.461 + // Swaps contents with the |other| list. 1.462 + virtual void Swap(ListValue* other); 1.463 + 1.464 + // Iteration. 1.465 + iterator begin() { return list_.begin(); } 1.466 + iterator end() { return list_.end(); } 1.467 + 1.468 + const_iterator begin() const { return list_.begin(); } 1.469 + const_iterator end() const { return list_.end(); } 1.470 + 1.471 + // Overridden from Value: 1.472 + virtual bool GetAsList(ListValue** out_value) OVERRIDE; 1.473 + virtual bool GetAsList(const ListValue** out_value) const OVERRIDE; 1.474 + virtual ListValue* DeepCopy() const OVERRIDE; 1.475 + virtual bool Equals(const Value* other) const OVERRIDE; 1.476 + 1.477 + private: 1.478 + ValueVector list_; 1.479 + 1.480 + DISALLOW_COPY_AND_ASSIGN(ListValue); 1.481 +}; 1.482 + 1.483 +// This interface is implemented by classes that know how to serialize and 1.484 +// deserialize Value objects. 1.485 +class BASE_EXPORT ValueSerializer { 1.486 + public: 1.487 + virtual ~ValueSerializer(); 1.488 + 1.489 + virtual bool Serialize(const Value& root) = 0; 1.490 + 1.491 + // This method deserializes the subclass-specific format into a Value object. 1.492 + // If the return value is non-NULL, the caller takes ownership of returned 1.493 + // Value. If the return value is NULL, and if error_code is non-NULL, 1.494 + // error_code will be set with the underlying error. 1.495 + // If |error_message| is non-null, it will be filled in with a formatted 1.496 + // error message including the location of the error if appropriate. 1.497 + virtual Value* Deserialize(int* error_code, std::string* error_str) = 0; 1.498 +}; 1.499 + 1.500 +// Stream operator so Values can be used in assertion statements. In order that 1.501 +// gtest uses this operator to print readable output on test failures, we must 1.502 +// override each specific type. Otherwise, the default template implementation 1.503 +// is preferred over an upcast. 1.504 +BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value); 1.505 + 1.506 +BASE_EXPORT inline std::ostream& operator<<(std::ostream& out, 1.507 + const FundamentalValue& value) { 1.508 + return out << static_cast<const Value&>(value); 1.509 +} 1.510 + 1.511 +BASE_EXPORT inline std::ostream& operator<<(std::ostream& out, 1.512 + const StringValue& value) { 1.513 + return out << static_cast<const Value&>(value); 1.514 +} 1.515 + 1.516 +BASE_EXPORT inline std::ostream& operator<<(std::ostream& out, 1.517 + const DictionaryValue& value) { 1.518 + return out << static_cast<const Value&>(value); 1.519 +} 1.520 + 1.521 +BASE_EXPORT inline std::ostream& operator<<(std::ostream& out, 1.522 + const ListValue& value) { 1.523 + return out << static_cast<const Value&>(value); 1.524 +} 1.525 + 1.526 +} // namespace base 1.527 + 1.528 +// http://crbug.com/88666 1.529 +using base::DictionaryValue; 1.530 +using base::ListValue; 1.531 +using base::StringValue; 1.532 +using base::Value; 1.533 + 1.534 +#endif // BASE_VALUES_H_