1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_VALUES_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_VALUES_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 9*6777b538SAndroid Build Coastguard Worker #include <stdint.h> 10*6777b538SAndroid Build Coastguard Worker 11*6777b538SAndroid Build Coastguard Worker #include <array> 12*6777b538SAndroid Build Coastguard Worker #include <initializer_list> 13*6777b538SAndroid Build Coastguard Worker #include <iosfwd> 14*6777b538SAndroid Build Coastguard Worker #include <iterator> 15*6777b538SAndroid Build Coastguard Worker #include <memory> 16*6777b538SAndroid Build Coastguard Worker #include <optional> 17*6777b538SAndroid Build Coastguard Worker #include <string> 18*6777b538SAndroid Build Coastguard Worker #include <utility> 19*6777b538SAndroid Build Coastguard Worker #include <vector> 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 22*6777b538SAndroid Build Coastguard Worker #include "base/bit_cast.h" 23*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h" 24*6777b538SAndroid Build Coastguard Worker #include "base/containers/checked_iterators.h" 25*6777b538SAndroid Build Coastguard Worker #include "base/containers/flat_map.h" 26*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h" 27*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ref.h" 28*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h" 29*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/base_tracing_forward.h" 30*6777b538SAndroid Build Coastguard Worker #include "base/value_iterators.h" 31*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/types/variant.h" 32*6777b538SAndroid Build Coastguard Worker 33*6777b538SAndroid Build Coastguard Worker namespace base { 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker // The `Value` class is a variant type can hold one of the following types: 36*6777b538SAndroid Build Coastguard Worker // - null 37*6777b538SAndroid Build Coastguard Worker // - bool 38*6777b538SAndroid Build Coastguard Worker // - int 39*6777b538SAndroid Build Coastguard Worker // - double 40*6777b538SAndroid Build Coastguard Worker // - string (internally UTF8-encoded) 41*6777b538SAndroid Build Coastguard Worker // - binary data (i.e. a blob) 42*6777b538SAndroid Build Coastguard Worker // - dictionary of string keys to `Value`s 43*6777b538SAndroid Build Coastguard Worker // - list of `Value`s 44*6777b538SAndroid Build Coastguard Worker // 45*6777b538SAndroid Build Coastguard Worker // With the exception of binary blobs, `Value` is intended to be the C++ version 46*6777b538SAndroid Build Coastguard Worker // of data types that can be represented in JSON. 47*6777b538SAndroid Build Coastguard Worker // 48*6777b538SAndroid Build Coastguard Worker // Warning: blob support may be removed in the future. 49*6777b538SAndroid Build Coastguard Worker // 50*6777b538SAndroid Build Coastguard Worker // ## Usage 51*6777b538SAndroid Build Coastguard Worker // 52*6777b538SAndroid Build Coastguard Worker // Do not use `Value` if a more specific type would be more appropriate. For 53*6777b538SAndroid Build Coastguard Worker // example, a function that only accepts dictionary values should have a 54*6777b538SAndroid Build Coastguard Worker // `base::Value::Dict` parameter, not a `base::Value` parameter. 55*6777b538SAndroid Build Coastguard Worker // 56*6777b538SAndroid Build Coastguard Worker // Construction: 57*6777b538SAndroid Build Coastguard Worker // 58*6777b538SAndroid Build Coastguard Worker // `Value` is directly constructible from `bool`, `int`, `double`, binary blobs 59*6777b538SAndroid Build Coastguard Worker // (`std::vector<uint8_t>`), `base::StringPiece`, `base::StringPiece16`, 60*6777b538SAndroid Build Coastguard Worker // `Value::Dict`, and `Value::List`. 61*6777b538SAndroid Build Coastguard Worker // 62*6777b538SAndroid Build Coastguard Worker // Copying: 63*6777b538SAndroid Build Coastguard Worker // 64*6777b538SAndroid Build Coastguard Worker // `Value` does not support C++ copy semantics to make it harder to accidentally 65*6777b538SAndroid Build Coastguard Worker // copy large values. Instead, use `Clone()` to manually create a deep copy. 66*6777b538SAndroid Build Coastguard Worker // 67*6777b538SAndroid Build Coastguard Worker // Reading: 68*6777b538SAndroid Build Coastguard Worker // 69*6777b538SAndroid Build Coastguard Worker // `GetBool()`, GetInt()`, et cetera `CHECK()` that the `Value` has the correct 70*6777b538SAndroid Build Coastguard Worker // subtype before returning the contained value. `bool`, `int`, `double` are 71*6777b538SAndroid Build Coastguard Worker // returned by value. Binary blobs, `std::string`, `Value::Dict`, `Value::List` 72*6777b538SAndroid Build Coastguard Worker // are returned by reference. 73*6777b538SAndroid Build Coastguard Worker // 74*6777b538SAndroid Build Coastguard Worker // `GetIfBool()`, `GetIfInt()`, et cetera return `std::nullopt`/`nullptr` if 75*6777b538SAndroid Build Coastguard Worker // the `Value` does not have the correct subtype; otherwise, returns the value 76*6777b538SAndroid Build Coastguard Worker // wrapped in an `std::optional` (for `bool`, `int`, `double`) or by pointer 77*6777b538SAndroid Build Coastguard Worker // (for binary blobs, `std::string`, `Value::Dict`, `Value::List`). 78*6777b538SAndroid Build Coastguard Worker // 79*6777b538SAndroid Build Coastguard Worker // Note: both `GetDouble()` and `GetIfDouble()` still return a non-null result 80*6777b538SAndroid Build Coastguard Worker // when the subtype is `Value::Type::INT`. In that case, the stored value is 81*6777b538SAndroid Build Coastguard Worker // coerced to a double before being returned. 82*6777b538SAndroid Build Coastguard Worker // 83*6777b538SAndroid Build Coastguard Worker // Assignment: 84*6777b538SAndroid Build Coastguard Worker // 85*6777b538SAndroid Build Coastguard Worker // It is not possible to directly assign `bool`, `int`, et cetera to a `Value`. 86*6777b538SAndroid Build Coastguard Worker // Instead, wrap the underlying type in `Value` before assigning. 87*6777b538SAndroid Build Coastguard Worker // 88*6777b538SAndroid Build Coastguard Worker // ## Dictionaries and Lists 89*6777b538SAndroid Build Coastguard Worker // 90*6777b538SAndroid Build Coastguard Worker // `Value` provides the `Value::Dict` and `Value::List` container types for 91*6777b538SAndroid Build Coastguard Worker // working with dictionaries and lists of values respectively, rather than 92*6777b538SAndroid Build Coastguard Worker // exposing the underlying container types directly. This allows the types to 93*6777b538SAndroid Build Coastguard Worker // provide convenient helpers for dictionaries and lists, as well as giving 94*6777b538SAndroid Build Coastguard Worker // greater flexibility for changing implementation details in the future. 95*6777b538SAndroid Build Coastguard Worker // 96*6777b538SAndroid Build Coastguard Worker // Both container types support enough STL-isms to be usable in range-based for 97*6777b538SAndroid Build Coastguard Worker // loops and generic operations such as those from <algorithm>. 98*6777b538SAndroid Build Coastguard Worker // 99*6777b538SAndroid Build Coastguard Worker // Dictionaries support: 100*6777b538SAndroid Build Coastguard Worker // - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`, 101*6777b538SAndroid Build Coastguard Worker // `contains()`, `clear()`, `erase()`: Identical to the STL container 102*6777b538SAndroid Build Coastguard Worker // equivalents, with additional safety checks, e.g. iterators will 103*6777b538SAndroid Build Coastguard Worker // `CHECK()` if `end()` is dereferenced. 104*6777b538SAndroid Build Coastguard Worker // 105*6777b538SAndroid Build Coastguard Worker // - `Clone()`: Create a deep copy. 106*6777b538SAndroid Build Coastguard Worker // - `Merge()`: Merge another dictionary into this dictionary. 107*6777b538SAndroid Build Coastguard Worker // - `Find()`: Find a value by `StringPiece` key, returning nullptr if the key 108*6777b538SAndroid Build Coastguard Worker // is not present. 109*6777b538SAndroid Build Coastguard Worker // - `FindBool()`, `FindInt()`, ...: Similar to `Find()`, but ensures that the 110*6777b538SAndroid Build Coastguard Worker // `Value` also has the correct subtype. Same return semantics as 111*6777b538SAndroid Build Coastguard Worker // `GetIfBool()`, `GetIfInt()`, et cetera, returning `std::nullopt` or 112*6777b538SAndroid Build Coastguard Worker // `nullptr` if the key is not present or the value has the wrong subtype. 113*6777b538SAndroid Build Coastguard Worker // - `Set()`: Associate a value with a `StringPiece` key. Accepts `Value` or any 114*6777b538SAndroid Build Coastguard Worker // of the subtypes that `Value` can hold. 115*6777b538SAndroid Build Coastguard Worker // - `Remove()`: Remove the key from this dictionary, if present. 116*6777b538SAndroid Build Coastguard Worker // - `Extract()`: If the key is present in the dictionary, removes the key from 117*6777b538SAndroid Build Coastguard Worker // the dictionary and transfers ownership of `Value` to the caller. 118*6777b538SAndroid Build Coastguard Worker // Otherwise, returns `std::nullopt`. 119*6777b538SAndroid Build Coastguard Worker // 120*6777b538SAndroid Build Coastguard Worker // Dictionaries also support an additional set of helper methods that operate on 121*6777b538SAndroid Build Coastguard Worker // "paths": `FindByDottedPath()`, `SetByDottedPath()`, `RemoveByDottedPath()`, 122*6777b538SAndroid Build Coastguard Worker // and `ExtractByDottedPath()`. Dotted paths are a convenience method of naming 123*6777b538SAndroid Build Coastguard Worker // intermediate nested dictionaries, separating the components of the path using 124*6777b538SAndroid Build Coastguard Worker // '.' characters. For example, finding a string path on a `Value::Dict` using 125*6777b538SAndroid Build Coastguard Worker // the dotted path: 126*6777b538SAndroid Build Coastguard Worker // 127*6777b538SAndroid Build Coastguard Worker // "aaa.bbb.ccc" 128*6777b538SAndroid Build Coastguard Worker // 129*6777b538SAndroid Build Coastguard Worker // Will first look for a `Value::Type::DICT` associated with the key "aaa", then 130*6777b538SAndroid Build Coastguard Worker // another `Value::Type::DICT` under the "aaa" dict associated with the 131*6777b538SAndroid Build Coastguard Worker // key "bbb", and then a `Value::Type::STRING` under the "bbb" dict associated 132*6777b538SAndroid Build Coastguard Worker // with the key "ccc". 133*6777b538SAndroid Build Coastguard Worker // 134*6777b538SAndroid Build Coastguard Worker // If a path only has one component (i.e. has no dots), please use the regular, 135*6777b538SAndroid Build Coastguard Worker // non-path APIs. 136*6777b538SAndroid Build Coastguard Worker // 137*6777b538SAndroid Build Coastguard Worker // Lists support: 138*6777b538SAndroid Build Coastguard Worker // - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`, 139*6777b538SAndroid Build Coastguard Worker // `rbegin()`, `rend()`, `front()`, `back()`, `reserve()`, `operator[]`, 140*6777b538SAndroid Build Coastguard Worker // `clear()`, `erase()`: Identical to the STL container equivalents, with 141*6777b538SAndroid Build Coastguard Worker // additional safety checks, e.g. `operator[]` will `CHECK()` if the index 142*6777b538SAndroid Build Coastguard Worker // is out of range. 143*6777b538SAndroid Build Coastguard Worker // - `Clone()`: Create a deep copy. 144*6777b538SAndroid Build Coastguard Worker // - `Append()`: Append a value to the end of the list. Accepts `Value` or any 145*6777b538SAndroid Build Coastguard Worker // of the subtypes that `Value` can hold. 146*6777b538SAndroid Build Coastguard Worker // - `Insert()`: Insert a `Value` at a specified point in the list. 147*6777b538SAndroid Build Coastguard Worker // - `EraseValue()`: Erases all matching `Value`s from the list. 148*6777b538SAndroid Build Coastguard Worker // - `EraseIf()`: Erase all `Value`s matching an arbitrary predicate from the 149*6777b538SAndroid Build Coastguard Worker // list. 150*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT GSL_OWNER Value { 151*6777b538SAndroid Build Coastguard Worker public: 152*6777b538SAndroid Build Coastguard Worker using BlobStorage = std::vector<uint8_t>; 153*6777b538SAndroid Build Coastguard Worker 154*6777b538SAndroid Build Coastguard Worker class Dict; 155*6777b538SAndroid Build Coastguard Worker class List; 156*6777b538SAndroid Build Coastguard Worker 157*6777b538SAndroid Build Coastguard Worker enum class Type : unsigned char { 158*6777b538SAndroid Build Coastguard Worker NONE = 0, 159*6777b538SAndroid Build Coastguard Worker BOOLEAN, 160*6777b538SAndroid Build Coastguard Worker INTEGER, 161*6777b538SAndroid Build Coastguard Worker DOUBLE, 162*6777b538SAndroid Build Coastguard Worker STRING, 163*6777b538SAndroid Build Coastguard Worker BINARY, 164*6777b538SAndroid Build Coastguard Worker DICT, 165*6777b538SAndroid Build Coastguard Worker LIST, 166*6777b538SAndroid Build Coastguard Worker // Note: Do not add more types. See the file-level comment above for why. 167*6777b538SAndroid Build Coastguard Worker }; 168*6777b538SAndroid Build Coastguard Worker 169*6777b538SAndroid Build Coastguard Worker // Adaptors for converting from the old way to the new way and vice versa. 170*6777b538SAndroid Build Coastguard Worker static Value FromUniquePtrValue(std::unique_ptr<Value> val); 171*6777b538SAndroid Build Coastguard Worker static std::unique_ptr<Value> ToUniquePtrValue(Value val); 172*6777b538SAndroid Build Coastguard Worker 173*6777b538SAndroid Build Coastguard Worker Value() noexcept; 174*6777b538SAndroid Build Coastguard Worker 175*6777b538SAndroid Build Coastguard Worker Value(Value&&) noexcept; 176*6777b538SAndroid Build Coastguard Worker Value& operator=(Value&&) noexcept; 177*6777b538SAndroid Build Coastguard Worker 178*6777b538SAndroid Build Coastguard Worker // Deleted to prevent accidental copying. 179*6777b538SAndroid Build Coastguard Worker Value(const Value&) = delete; 180*6777b538SAndroid Build Coastguard Worker Value& operator=(const Value&) = delete; 181*6777b538SAndroid Build Coastguard Worker 182*6777b538SAndroid Build Coastguard Worker // Creates a deep copy of this value. 183*6777b538SAndroid Build Coastguard Worker Value Clone() const; 184*6777b538SAndroid Build Coastguard Worker 185*6777b538SAndroid Build Coastguard Worker // Creates a `Value` of `type`. The data of the corresponding type will be 186*6777b538SAndroid Build Coastguard Worker // default constructed. 187*6777b538SAndroid Build Coastguard Worker explicit Value(Type type); 188*6777b538SAndroid Build Coastguard Worker 189*6777b538SAndroid Build Coastguard Worker // Constructor for `Value::Type::BOOLEAN`. 190*6777b538SAndroid Build Coastguard Worker explicit Value(bool value); 191*6777b538SAndroid Build Coastguard Worker 192*6777b538SAndroid Build Coastguard Worker // Prevent pointers from implicitly converting to bool. Another way to write 193*6777b538SAndroid Build Coastguard Worker // this would be to template the bool constructor and use SFINAE to only allow 194*6777b538SAndroid Build Coastguard Worker // use if `std::is_same_v<T, bool>` is true, but this has surprising behavior 195*6777b538SAndroid Build Coastguard Worker // with range-based for loops over a `std::vector<bool>` (which will 196*6777b538SAndroid Build Coastguard Worker // unintuitively match the int overload instead). 197*6777b538SAndroid Build Coastguard Worker // 198*6777b538SAndroid Build Coastguard Worker // The `const` is load-bearing; otherwise, a `char*` argument would prefer the 199*6777b538SAndroid Build Coastguard Worker // deleted overload due to requiring a qualification conversion. 200*6777b538SAndroid Build Coastguard Worker template <typename T> 201*6777b538SAndroid Build Coastguard Worker explicit Value(const T*) = delete; 202*6777b538SAndroid Build Coastguard Worker 203*6777b538SAndroid Build Coastguard Worker // Constructor for `Value::Type::INT`. 204*6777b538SAndroid Build Coastguard Worker explicit Value(int value); 205*6777b538SAndroid Build Coastguard Worker 206*6777b538SAndroid Build Coastguard Worker // Constructor for `Value::Type::DOUBLE`. 207*6777b538SAndroid Build Coastguard Worker explicit Value(double value); 208*6777b538SAndroid Build Coastguard Worker 209*6777b538SAndroid Build Coastguard Worker // Constructors for `Value::Type::STRING`. 210*6777b538SAndroid Build Coastguard Worker explicit Value(StringPiece value); 211*6777b538SAndroid Build Coastguard Worker explicit Value(StringPiece16 value); 212*6777b538SAndroid Build Coastguard Worker // `char*` and `char16_t*` are needed to provide a more specific overload than 213*6777b538SAndroid Build Coastguard Worker // the deleted `const T*` overload above. 214*6777b538SAndroid Build Coastguard Worker explicit Value(const char* value); 215*6777b538SAndroid Build Coastguard Worker explicit Value(const char16_t* value); 216*6777b538SAndroid Build Coastguard Worker // `std::string&&` allows for efficient move construction. 217*6777b538SAndroid Build Coastguard Worker explicit Value(std::string&& value) noexcept; 218*6777b538SAndroid Build Coastguard Worker 219*6777b538SAndroid Build Coastguard Worker // Constructors for `Value::Type::BINARY`. 220*6777b538SAndroid Build Coastguard Worker explicit Value(const std::vector<char>& value); 221*6777b538SAndroid Build Coastguard Worker explicit Value(base::span<const uint8_t> value); 222*6777b538SAndroid Build Coastguard Worker explicit Value(BlobStorage&& value) noexcept; 223*6777b538SAndroid Build Coastguard Worker 224*6777b538SAndroid Build Coastguard Worker // Constructor for `Value::Type::DICT`. 225*6777b538SAndroid Build Coastguard Worker explicit Value(Dict&& value) noexcept; 226*6777b538SAndroid Build Coastguard Worker 227*6777b538SAndroid Build Coastguard Worker // Constructor for `Value::Type::LIST`. 228*6777b538SAndroid Build Coastguard Worker explicit Value(List&& value) noexcept; 229*6777b538SAndroid Build Coastguard Worker 230*6777b538SAndroid Build Coastguard Worker ~Value(); 231*6777b538SAndroid Build Coastguard Worker 232*6777b538SAndroid Build Coastguard Worker // Returns the name for a given `type`. 233*6777b538SAndroid Build Coastguard Worker static const char* GetTypeName(Type type); 234*6777b538SAndroid Build Coastguard Worker 235*6777b538SAndroid Build Coastguard Worker // Returns the type of the value stored by the current Value object. type()236*6777b538SAndroid Build Coastguard Worker Type type() const { return static_cast<Type>(data_.index()); } 237*6777b538SAndroid Build Coastguard Worker 238*6777b538SAndroid Build Coastguard Worker // Returns true if the current object represents a given type. is_none()239*6777b538SAndroid Build Coastguard Worker bool is_none() const { return type() == Type::NONE; } is_bool()240*6777b538SAndroid Build Coastguard Worker bool is_bool() const { return type() == Type::BOOLEAN; } is_int()241*6777b538SAndroid Build Coastguard Worker bool is_int() const { return type() == Type::INTEGER; } is_double()242*6777b538SAndroid Build Coastguard Worker bool is_double() const { return type() == Type::DOUBLE; } is_string()243*6777b538SAndroid Build Coastguard Worker bool is_string() const { return type() == Type::STRING; } is_blob()244*6777b538SAndroid Build Coastguard Worker bool is_blob() const { return type() == Type::BINARY; } is_dict()245*6777b538SAndroid Build Coastguard Worker bool is_dict() const { return type() == Type::DICT; } is_list()246*6777b538SAndroid Build Coastguard Worker bool is_list() const { return type() == Type::LIST; } 247*6777b538SAndroid Build Coastguard Worker 248*6777b538SAndroid Build Coastguard Worker // Returns the stored data if the type matches, or `std::nullopt`/`nullptr` 249*6777b538SAndroid Build Coastguard Worker // otherwise. `bool`, `int`, and `double` are returned in a wrapped 250*6777b538SAndroid Build Coastguard Worker // `std::optional`; blobs, `Value::Dict`, and `Value::List` are returned by 251*6777b538SAndroid Build Coastguard Worker // pointer. 252*6777b538SAndroid Build Coastguard Worker std::optional<bool> GetIfBool() const; 253*6777b538SAndroid Build Coastguard Worker std::optional<int> GetIfInt() const; 254*6777b538SAndroid Build Coastguard Worker // Returns a non-null value for both `Value::Type::DOUBLE` and 255*6777b538SAndroid Build Coastguard Worker // `Value::Type::INT`, converting the latter to a double. 256*6777b538SAndroid Build Coastguard Worker std::optional<double> GetIfDouble() const; 257*6777b538SAndroid Build Coastguard Worker const std::string* GetIfString() const; 258*6777b538SAndroid Build Coastguard Worker std::string* GetIfString(); 259*6777b538SAndroid Build Coastguard Worker const BlobStorage* GetIfBlob() const; 260*6777b538SAndroid Build Coastguard Worker const Dict* GetIfDict() const; 261*6777b538SAndroid Build Coastguard Worker Dict* GetIfDict(); 262*6777b538SAndroid Build Coastguard Worker const List* GetIfList() const; 263*6777b538SAndroid Build Coastguard Worker List* GetIfList(); 264*6777b538SAndroid Build Coastguard Worker 265*6777b538SAndroid Build Coastguard Worker // Similar to the `GetIf...()` variants above, but fails with a `CHECK()` on a 266*6777b538SAndroid Build Coastguard Worker // type mismatch. `bool`, `int`, and `double` are returned by value; blobs, 267*6777b538SAndroid Build Coastguard Worker // `Value::Dict`, and `Value::List` are returned by reference. 268*6777b538SAndroid Build Coastguard Worker bool GetBool() const; 269*6777b538SAndroid Build Coastguard Worker int GetInt() const; 270*6777b538SAndroid Build Coastguard Worker // Returns a value for both `Value::Type::DOUBLE` and `Value::Type::INT`, 271*6777b538SAndroid Build Coastguard Worker // converting the latter to a double. 272*6777b538SAndroid Build Coastguard Worker double GetDouble() const; 273*6777b538SAndroid Build Coastguard Worker const std::string& GetString() const; 274*6777b538SAndroid Build Coastguard Worker std::string& GetString(); 275*6777b538SAndroid Build Coastguard Worker const BlobStorage& GetBlob() const; 276*6777b538SAndroid Build Coastguard Worker const Dict& GetDict() const; 277*6777b538SAndroid Build Coastguard Worker Dict& GetDict(); 278*6777b538SAndroid Build Coastguard Worker const List& GetList() const; 279*6777b538SAndroid Build Coastguard Worker List& GetList(); 280*6777b538SAndroid Build Coastguard Worker 281*6777b538SAndroid Build Coastguard Worker // Transfers ownership of the underlying value. Similarly to `Get...()` 282*6777b538SAndroid Build Coastguard Worker // variants above, fails with a `CHECK()` on a type mismatch. After 283*6777b538SAndroid Build Coastguard Worker // transferring the ownership `*this` is in a valid, but unspecified, state. 284*6777b538SAndroid Build Coastguard Worker // Prefer over `std::move(value.Get...())` so clang-tidy can warn about 285*6777b538SAndroid Build Coastguard Worker // potential use-after-move mistakes. 286*6777b538SAndroid Build Coastguard Worker std::string TakeString() &&; 287*6777b538SAndroid Build Coastguard Worker Dict TakeDict() &&; 288*6777b538SAndroid Build Coastguard Worker List TakeList() &&; 289*6777b538SAndroid Build Coastguard Worker 290*6777b538SAndroid Build Coastguard Worker // Represents a dictionary of string keys to Values. 291*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT GSL_OWNER Dict { 292*6777b538SAndroid Build Coastguard Worker public: 293*6777b538SAndroid Build Coastguard Worker using iterator = detail::dict_iterator; 294*6777b538SAndroid Build Coastguard Worker using const_iterator = detail::const_dict_iterator; 295*6777b538SAndroid Build Coastguard Worker 296*6777b538SAndroid Build Coastguard Worker Dict(); 297*6777b538SAndroid Build Coastguard Worker 298*6777b538SAndroid Build Coastguard Worker Dict(Dict&&) noexcept; 299*6777b538SAndroid Build Coastguard Worker Dict& operator=(Dict&&) noexcept; 300*6777b538SAndroid Build Coastguard Worker 301*6777b538SAndroid Build Coastguard Worker // Deleted to prevent accidental copying. 302*6777b538SAndroid Build Coastguard Worker Dict(const Dict&) = delete; 303*6777b538SAndroid Build Coastguard Worker Dict& operator=(const Dict&) = delete; 304*6777b538SAndroid Build Coastguard Worker 305*6777b538SAndroid Build Coastguard Worker // Takes move_iterators iterators that return std::pair<std::string, Value>, 306*6777b538SAndroid Build Coastguard Worker // and moves their values into a new Dict. Adding all entries at once 307*6777b538SAndroid Build Coastguard Worker // results in a faster initial sort operation. Takes move iterators to avoid 308*6777b538SAndroid Build Coastguard Worker // having to clone the input. 309*6777b538SAndroid Build Coastguard Worker template <class IteratorType> Dict(std::move_iterator<IteratorType> first,std::move_iterator<IteratorType> last)310*6777b538SAndroid Build Coastguard Worker explicit Dict(std::move_iterator<IteratorType> first, 311*6777b538SAndroid Build Coastguard Worker std::move_iterator<IteratorType> last) { 312*6777b538SAndroid Build Coastguard Worker // Need to move into a vector first, since `storage_` currently uses 313*6777b538SAndroid Build Coastguard Worker // unique_ptrs. 314*6777b538SAndroid Build Coastguard Worker std::vector<std::pair<std::string, std::unique_ptr<Value>>> values; 315*6777b538SAndroid Build Coastguard Worker for (auto current = first; current != last; ++current) { 316*6777b538SAndroid Build Coastguard Worker // With move iterators, no need to call Clone(), but do need to move 317*6777b538SAndroid Build Coastguard Worker // to a temporary first, as accessing either field individually will 318*6777b538SAndroid Build Coastguard Worker // directly from the iterator will delete the other field. 319*6777b538SAndroid Build Coastguard Worker auto value = *current; 320*6777b538SAndroid Build Coastguard Worker values.emplace_back(std::move(value.first), 321*6777b538SAndroid Build Coastguard Worker std::make_unique<Value>(std::move(value.second))); 322*6777b538SAndroid Build Coastguard Worker } 323*6777b538SAndroid Build Coastguard Worker storage_ = 324*6777b538SAndroid Build Coastguard Worker flat_map<std::string, std::unique_ptr<Value>>(std::move(values)); 325*6777b538SAndroid Build Coastguard Worker } 326*6777b538SAndroid Build Coastguard Worker 327*6777b538SAndroid Build Coastguard Worker ~Dict(); 328*6777b538SAndroid Build Coastguard Worker 329*6777b538SAndroid Build Coastguard Worker // Returns true if there are no entries in this dictionary and false 330*6777b538SAndroid Build Coastguard Worker // otherwise. 331*6777b538SAndroid Build Coastguard Worker bool empty() const; 332*6777b538SAndroid Build Coastguard Worker 333*6777b538SAndroid Build Coastguard Worker // Returns the number of entries in this dictionary. 334*6777b538SAndroid Build Coastguard Worker size_t size() const; 335*6777b538SAndroid Build Coastguard Worker 336*6777b538SAndroid Build Coastguard Worker // Returns an iterator to the first entry in this dictionary. 337*6777b538SAndroid Build Coastguard Worker iterator begin(); 338*6777b538SAndroid Build Coastguard Worker const_iterator begin() const; 339*6777b538SAndroid Build Coastguard Worker const_iterator cbegin() const; 340*6777b538SAndroid Build Coastguard Worker 341*6777b538SAndroid Build Coastguard Worker // Returns an iterator following the last entry in this dictionary. May not 342*6777b538SAndroid Build Coastguard Worker // be dereferenced. 343*6777b538SAndroid Build Coastguard Worker iterator end(); 344*6777b538SAndroid Build Coastguard Worker const_iterator end() const; 345*6777b538SAndroid Build Coastguard Worker const_iterator cend() const; 346*6777b538SAndroid Build Coastguard Worker 347*6777b538SAndroid Build Coastguard Worker // Returns true if `key` is an entry in this dictionary. 348*6777b538SAndroid Build Coastguard Worker bool contains(base::StringPiece key) const; 349*6777b538SAndroid Build Coastguard Worker 350*6777b538SAndroid Build Coastguard Worker // Removes all entries from this dictionary. 351*6777b538SAndroid Build Coastguard Worker REINITIALIZES_AFTER_MOVE void clear(); 352*6777b538SAndroid Build Coastguard Worker 353*6777b538SAndroid Build Coastguard Worker // Removes the entry referenced by `pos` in this dictionary and returns an 354*6777b538SAndroid Build Coastguard Worker // iterator to the entry following the removed entry. 355*6777b538SAndroid Build Coastguard Worker iterator erase(iterator pos); 356*6777b538SAndroid Build Coastguard Worker iterator erase(const_iterator pos); 357*6777b538SAndroid Build Coastguard Worker 358*6777b538SAndroid Build Coastguard Worker // Creates a deep copy of this dictionary. 359*6777b538SAndroid Build Coastguard Worker Dict Clone() const; 360*6777b538SAndroid Build Coastguard Worker 361*6777b538SAndroid Build Coastguard Worker // Merges the entries from `dict` into this dictionary. If an entry with the 362*6777b538SAndroid Build Coastguard Worker // same key exists in this dictionary and `dict`: 363*6777b538SAndroid Build Coastguard Worker // - if both entries are dictionaries, they will be recursively merged 364*6777b538SAndroid Build Coastguard Worker // - otherwise, the already-existing entry in this dictionary will be 365*6777b538SAndroid Build Coastguard Worker // overwritten with the entry from `dict`. 366*6777b538SAndroid Build Coastguard Worker void Merge(Dict dict); 367*6777b538SAndroid Build Coastguard Worker 368*6777b538SAndroid Build Coastguard Worker // Finds the entry corresponding to `key` in this dictionary. Returns 369*6777b538SAndroid Build Coastguard Worker // nullptr if there is no such entry. 370*6777b538SAndroid Build Coastguard Worker const Value* Find(StringPiece key) const; 371*6777b538SAndroid Build Coastguard Worker Value* Find(StringPiece key); 372*6777b538SAndroid Build Coastguard Worker 373*6777b538SAndroid Build Coastguard Worker // Similar to `Find()` above, but returns `std::nullopt`/`nullptr` if the 374*6777b538SAndroid Build Coastguard Worker // type of the entry does not match. `bool`, `int`, and `double` are 375*6777b538SAndroid Build Coastguard Worker // returned in a wrapped `std::optional`; blobs, `Value::Dict`, and 376*6777b538SAndroid Build Coastguard Worker // `Value::List` are returned by pointer. 377*6777b538SAndroid Build Coastguard Worker std::optional<bool> FindBool(StringPiece key) const; 378*6777b538SAndroid Build Coastguard Worker std::optional<int> FindInt(StringPiece key) const; 379*6777b538SAndroid Build Coastguard Worker // Returns a non-null value for both `Value::Type::DOUBLE` and 380*6777b538SAndroid Build Coastguard Worker // `Value::Type::INT`, converting the latter to a double. 381*6777b538SAndroid Build Coastguard Worker std::optional<double> FindDouble(StringPiece key) const; 382*6777b538SAndroid Build Coastguard Worker const std::string* FindString(StringPiece key) const; 383*6777b538SAndroid Build Coastguard Worker std::string* FindString(StringPiece key); 384*6777b538SAndroid Build Coastguard Worker const BlobStorage* FindBlob(StringPiece key) const; 385*6777b538SAndroid Build Coastguard Worker const Dict* FindDict(StringPiece key) const; 386*6777b538SAndroid Build Coastguard Worker Dict* FindDict(StringPiece key); 387*6777b538SAndroid Build Coastguard Worker const List* FindList(StringPiece key) const; 388*6777b538SAndroid Build Coastguard Worker List* FindList(StringPiece key); 389*6777b538SAndroid Build Coastguard Worker 390*6777b538SAndroid Build Coastguard Worker // If there's a value of the specified type at `key` in this dictionary, 391*6777b538SAndroid Build Coastguard Worker // returns it. Otherwise, creates an empty container of the specified type, 392*6777b538SAndroid Build Coastguard Worker // inserts it at `key`, and returns it. If there's a value of some other 393*6777b538SAndroid Build Coastguard Worker // type at `key`, will overwrite that entry. 394*6777b538SAndroid Build Coastguard Worker Dict* EnsureDict(StringPiece key); 395*6777b538SAndroid Build Coastguard Worker List* EnsureList(StringPiece key); 396*6777b538SAndroid Build Coastguard Worker 397*6777b538SAndroid Build Coastguard Worker // Sets an entry with `key` and `value` in this dictionary, overwriting any 398*6777b538SAndroid Build Coastguard Worker // existing entry with the same `key`. Returns a pointer to the set `value`. 399*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, Value&& value) &; 400*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, bool value) &; 401*6777b538SAndroid Build Coastguard Worker template <typename T> 402*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece, const T*) & = delete; 403*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, int value) &; 404*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, double value) &; 405*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, StringPiece value) &; 406*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, StringPiece16 value) &; 407*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, const char* value) &; 408*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, const char16_t* value) &; 409*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, std::string&& value) &; 410*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, BlobStorage&& value) &; 411*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, Dict&& value) &; 412*6777b538SAndroid Build Coastguard Worker Value* Set(StringPiece key, List&& value) &; 413*6777b538SAndroid Build Coastguard Worker 414*6777b538SAndroid Build Coastguard Worker // Rvalue overrides of the `Set` methods, which allow you to construct 415*6777b538SAndroid Build Coastguard Worker // a `Value::Dict` builder-style: 416*6777b538SAndroid Build Coastguard Worker // 417*6777b538SAndroid Build Coastguard Worker // Value::Dict result = 418*6777b538SAndroid Build Coastguard Worker // Value::Dict() 419*6777b538SAndroid Build Coastguard Worker // .Set("key-1", "first value") 420*6777b538SAndroid Build Coastguard Worker // .Set("key-2", 2) 421*6777b538SAndroid Build Coastguard Worker // .Set("key-3", true) 422*6777b538SAndroid Build Coastguard Worker // .Set("nested-dictionary", Value::Dict() 423*6777b538SAndroid Build Coastguard Worker // .Set("nested-key-1", "value") 424*6777b538SAndroid Build Coastguard Worker // .Set("nested-key-2", true)) 425*6777b538SAndroid Build Coastguard Worker // .Set("nested-list", Value::List() 426*6777b538SAndroid Build Coastguard Worker // .Append("nested-list-value") 427*6777b538SAndroid Build Coastguard Worker // .Append(5) 428*6777b538SAndroid Build Coastguard Worker // .Append(true)); 429*6777b538SAndroid Build Coastguard Worker // 430*6777b538SAndroid Build Coastguard Worker // Each method returns a rvalue reference to `this`, so this is as efficient 431*6777b538SAndroid Build Coastguard Worker // as stand-alone calls to `Set`, while also making it harder to 432*6777b538SAndroid Build Coastguard Worker // accidentally insert items in the wrong dictionary. 433*6777b538SAndroid Build Coastguard Worker // 434*6777b538SAndroid Build Coastguard Worker // The equivalent code without using these builder-style methods: 435*6777b538SAndroid Build Coastguard Worker // 436*6777b538SAndroid Build Coastguard Worker // Value::Dict no_builder_example; 437*6777b538SAndroid Build Coastguard Worker // no_builder_example.Set("key-1", "first value") 438*6777b538SAndroid Build Coastguard Worker // no_builder_example.Set("key-2", 2) 439*6777b538SAndroid Build Coastguard Worker // no_builder_example.Set("key-3", true) 440*6777b538SAndroid Build Coastguard Worker // Value::Dict nested_dictionary; 441*6777b538SAndroid Build Coastguard Worker // nested_dictionary.Set("nested-key-1", "value"); 442*6777b538SAndroid Build Coastguard Worker // nested_dictionary.Set("nested-key-2", true); 443*6777b538SAndroid Build Coastguard Worker // no_builder_example.Set("nested_dictionary", 444*6777b538SAndroid Build Coastguard Worker // std::move(nested_dictionary)); 445*6777b538SAndroid Build Coastguard Worker // Value::List nested_list; 446*6777b538SAndroid Build Coastguard Worker // nested_list.Append("nested-list-value"); 447*6777b538SAndroid Build Coastguard Worker // nested_list.Append(5); 448*6777b538SAndroid Build Coastguard Worker // nested_list.Append(true); 449*6777b538SAndroid Build Coastguard Worker // no_builder_example.Set("nested-list", std::move(nested_list)); 450*6777b538SAndroid Build Coastguard Worker // 451*6777b538SAndroid Build Coastguard Worker // Sometimes `git cl format` does a less than perfect job formatting these 452*6777b538SAndroid Build Coastguard Worker // chained `Set` calls. In these cases you can use a trailing empty comment 453*6777b538SAndroid Build Coastguard Worker // to influence the code formatting: 454*6777b538SAndroid Build Coastguard Worker // 455*6777b538SAndroid Build Coastguard Worker // Value::Dict result = Value::Dict().Set( 456*6777b538SAndroid Build Coastguard Worker // "nested", 457*6777b538SAndroid Build Coastguard Worker // base::Value::Dict().Set("key", "value").Set("other key", "other")); 458*6777b538SAndroid Build Coastguard Worker // 459*6777b538SAndroid Build Coastguard Worker // Value::Dict result = Value::Dict().Set("nested", 460*6777b538SAndroid Build Coastguard Worker // base::Value::Dict() // 461*6777b538SAndroid Build Coastguard Worker // .Set("key", "value") 462*6777b538SAndroid Build Coastguard Worker // .Set("other key", "value")); 463*6777b538SAndroid Build Coastguard Worker // 464*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, Value&& value) &&; 465*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, bool value) &&; 466*6777b538SAndroid Build Coastguard Worker template <typename T> 467*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece, const T*) && = delete; 468*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, int value) &&; 469*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, double value) &&; 470*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, StringPiece value) &&; 471*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, StringPiece16 value) &&; 472*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, const char* value) &&; 473*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, const char16_t* value) &&; 474*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, std::string&& value) &&; 475*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, BlobStorage&& value) &&; 476*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, Dict&& value) &&; 477*6777b538SAndroid Build Coastguard Worker Dict&& Set(StringPiece key, List&& value) &&; 478*6777b538SAndroid Build Coastguard Worker 479*6777b538SAndroid Build Coastguard Worker // Removes the entry corresponding to `key` from this dictionary. Returns 480*6777b538SAndroid Build Coastguard Worker // true if an entry was removed or false otherwise. 481*6777b538SAndroid Build Coastguard Worker bool Remove(StringPiece key); 482*6777b538SAndroid Build Coastguard Worker 483*6777b538SAndroid Build Coastguard Worker // Similar to `Remove()`, but returns the value corresponding to the removed 484*6777b538SAndroid Build Coastguard Worker // entry or `std::nullopt` otherwise. 485*6777b538SAndroid Build Coastguard Worker std::optional<Value> Extract(StringPiece key); 486*6777b538SAndroid Build Coastguard Worker 487*6777b538SAndroid Build Coastguard Worker // Equivalent to the above methods but operating on paths instead of keys. 488*6777b538SAndroid Build Coastguard Worker // A path is shorthand syntax for referring to a key nested inside 489*6777b538SAndroid Build Coastguard Worker // intermediate dictionaries, with components delimited by ".". Paths may 490*6777b538SAndroid Build Coastguard Worker // not be empty. 491*6777b538SAndroid Build Coastguard Worker // 492*6777b538SAndroid Build Coastguard Worker // Prefer the non-path methods above when possible. Paths that have only one 493*6777b538SAndroid Build Coastguard Worker // component (i.e. no dots in the path) should never use the path-based 494*6777b538SAndroid Build Coastguard Worker // methods. 495*6777b538SAndroid Build Coastguard Worker // 496*6777b538SAndroid Build Coastguard Worker // Originally, the path-based APIs were the only way of specifying a key, so 497*6777b538SAndroid Build Coastguard Worker // there are likely to be many legacy (and unnecessary) uses of the path 498*6777b538SAndroid Build Coastguard Worker // APIs that do not actually require traversing nested dictionaries. 499*6777b538SAndroid Build Coastguard Worker const Value* FindByDottedPath(StringPiece path) const; 500*6777b538SAndroid Build Coastguard Worker Value* FindByDottedPath(StringPiece path); 501*6777b538SAndroid Build Coastguard Worker 502*6777b538SAndroid Build Coastguard Worker std::optional<bool> FindBoolByDottedPath(StringPiece path) const; 503*6777b538SAndroid Build Coastguard Worker std::optional<int> FindIntByDottedPath(StringPiece path) const; 504*6777b538SAndroid Build Coastguard Worker // Returns a non-null value for both `Value::Type::DOUBLE` and 505*6777b538SAndroid Build Coastguard Worker // `Value::Type::INT`, converting the latter to a double. 506*6777b538SAndroid Build Coastguard Worker std::optional<double> FindDoubleByDottedPath(StringPiece path) const; 507*6777b538SAndroid Build Coastguard Worker const std::string* FindStringByDottedPath(StringPiece path) const; 508*6777b538SAndroid Build Coastguard Worker std::string* FindStringByDottedPath(StringPiece path); 509*6777b538SAndroid Build Coastguard Worker const BlobStorage* FindBlobByDottedPath(StringPiece path) const; 510*6777b538SAndroid Build Coastguard Worker const Dict* FindDictByDottedPath(StringPiece path) const; 511*6777b538SAndroid Build Coastguard Worker Dict* FindDictByDottedPath(StringPiece path); 512*6777b538SAndroid Build Coastguard Worker const List* FindListByDottedPath(StringPiece path) const; 513*6777b538SAndroid Build Coastguard Worker List* FindListByDottedPath(StringPiece path); 514*6777b538SAndroid Build Coastguard Worker 515*6777b538SAndroid Build Coastguard Worker // Creates a new entry with a dictionary for any non-last component that is 516*6777b538SAndroid Build Coastguard Worker // missing an entry while performing the path traversal. Will fail if any 517*6777b538SAndroid Build Coastguard Worker // non-last component of the path refers to an already-existing entry that 518*6777b538SAndroid Build Coastguard Worker // is not a dictionary. Returns `nullptr` on failure. 519*6777b538SAndroid Build Coastguard Worker // 520*6777b538SAndroid Build Coastguard Worker // Warning: repeatedly using this API to enter entries in the same nested 521*6777b538SAndroid Build Coastguard Worker // dictionary is inefficient, so please do not write the following: 522*6777b538SAndroid Build Coastguard Worker // 523*6777b538SAndroid Build Coastguard Worker // bad_example.SetByDottedPath("a.nested.dictionary.field_1", 1); 524*6777b538SAndroid Build Coastguard Worker // bad_example.SetByDottedPath("a.nested.dictionary.field_2", "value"); 525*6777b538SAndroid Build Coastguard Worker // bad_example.SetByDottedPath("a.nested.dictionary.field_3", 1); 526*6777b538SAndroid Build Coastguard Worker // 527*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, Value&& value) &; 528*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, bool value) &; 529*6777b538SAndroid Build Coastguard Worker template <typename T> 530*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece, const T*) & = delete; 531*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, int value) &; 532*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, double value) &; 533*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, StringPiece value) &; 534*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, StringPiece16 value) &; 535*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, const char* value) &; 536*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, const char16_t* value) &; 537*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, std::string&& value) &; 538*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, BlobStorage&& value) &; 539*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, Dict&& value) &; 540*6777b538SAndroid Build Coastguard Worker Value* SetByDottedPath(StringPiece path, List&& value) &; 541*6777b538SAndroid Build Coastguard Worker 542*6777b538SAndroid Build Coastguard Worker // Rvalue overrides of the `SetByDottedPath` methods, which allow you to 543*6777b538SAndroid Build Coastguard Worker // construct a `Value::Dict` builder-style: 544*6777b538SAndroid Build Coastguard Worker // 545*6777b538SAndroid Build Coastguard Worker // Value::Dict result = 546*6777b538SAndroid Build Coastguard Worker // Value::Dict() 547*6777b538SAndroid Build Coastguard Worker // .SetByDottedPath("a.nested.dictionary.with.key-1", "first value") 548*6777b538SAndroid Build Coastguard Worker // .Set("local-key-1", 2)); 549*6777b538SAndroid Build Coastguard Worker // 550*6777b538SAndroid Build Coastguard Worker // Each method returns a rvalue reference to `this`, so this is as efficient 551*6777b538SAndroid Build Coastguard Worker // as (and less mistake-prone than) stand-alone calls to `Set`. 552*6777b538SAndroid Build Coastguard Worker // 553*6777b538SAndroid Build Coastguard Worker // Warning: repeatedly using this API to enter entries in the same nested 554*6777b538SAndroid Build Coastguard Worker // dictionary is inefficient, so do not write this: 555*6777b538SAndroid Build Coastguard Worker // 556*6777b538SAndroid Build Coastguard Worker // Value::Dict bad_example = 557*6777b538SAndroid Build Coastguard Worker // Value::Dict() 558*6777b538SAndroid Build Coastguard Worker // .SetByDottedPath("nested.dictionary.key-1", "first value") 559*6777b538SAndroid Build Coastguard Worker // .SetByDottedPath("nested.dictionary.key-2", "second value") 560*6777b538SAndroid Build Coastguard Worker // .SetByDottedPath("nested.dictionary.key-3", "third value"); 561*6777b538SAndroid Build Coastguard Worker // 562*6777b538SAndroid Build Coastguard Worker // Instead, simply write this 563*6777b538SAndroid Build Coastguard Worker // 564*6777b538SAndroid Build Coastguard Worker // Value::Dict good_example = 565*6777b538SAndroid Build Coastguard Worker // Value::Dict() 566*6777b538SAndroid Build Coastguard Worker // .Set("nested", 567*6777b538SAndroid Build Coastguard Worker // base::Value::Dict() 568*6777b538SAndroid Build Coastguard Worker // .Set("dictionary", 569*6777b538SAndroid Build Coastguard Worker // base::Value::Dict() 570*6777b538SAndroid Build Coastguard Worker // .Set(key-1", "first value") 571*6777b538SAndroid Build Coastguard Worker // .Set(key-2", "second value") 572*6777b538SAndroid Build Coastguard Worker // .Set(key-3", "third value"))); 573*6777b538SAndroid Build Coastguard Worker // 574*6777b538SAndroid Build Coastguard Worker // 575*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, Value&& value) &&; 576*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, bool value) &&; 577*6777b538SAndroid Build Coastguard Worker template <typename T> 578*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece, const T*) && = delete; 579*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, int value) &&; 580*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, double value) &&; 581*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, StringPiece value) &&; 582*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, StringPiece16 value) &&; 583*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, const char* value) &&; 584*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, const char16_t* value) &&; 585*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, std::string&& value) &&; 586*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, BlobStorage&& value) &&; 587*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, Dict&& value) &&; 588*6777b538SAndroid Build Coastguard Worker Dict&& SetByDottedPath(StringPiece path, List&& value) &&; 589*6777b538SAndroid Build Coastguard Worker 590*6777b538SAndroid Build Coastguard Worker bool RemoveByDottedPath(StringPiece path); 591*6777b538SAndroid Build Coastguard Worker 592*6777b538SAndroid Build Coastguard Worker std::optional<Value> ExtractByDottedPath(StringPiece path); 593*6777b538SAndroid Build Coastguard Worker 594*6777b538SAndroid Build Coastguard Worker // Estimates dynamic memory usage. Requires tracing support 595*6777b538SAndroid Build Coastguard Worker // (enable_base_tracing gn flag), otherwise always returns 0. See 596*6777b538SAndroid Build Coastguard Worker // base/trace_event/memory_usage_estimator.h for more info. 597*6777b538SAndroid Build Coastguard Worker size_t EstimateMemoryUsage() const; 598*6777b538SAndroid Build Coastguard Worker 599*6777b538SAndroid Build Coastguard Worker // Serializes to a string for logging and debug purposes. 600*6777b538SAndroid Build Coastguard Worker std::string DebugString() const; 601*6777b538SAndroid Build Coastguard Worker 602*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BASE_TRACING) 603*6777b538SAndroid Build Coastguard Worker // Write this object into a trace. 604*6777b538SAndroid Build Coastguard Worker void WriteIntoTrace(perfetto::TracedValue) const; 605*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(ENABLE_BASE_TRACING) 606*6777b538SAndroid Build Coastguard Worker 607*6777b538SAndroid Build Coastguard Worker private: 608*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const Dict& lhs, const Dict& rhs); 609*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator!=(const Dict& lhs, const Dict& rhs); 610*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator<(const Dict& lhs, const Dict& rhs); 611*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator>(const Dict& lhs, const Dict& rhs); 612*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator<=(const Dict& lhs, const Dict& rhs); 613*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator>=(const Dict& lhs, const Dict& rhs); 614*6777b538SAndroid Build Coastguard Worker 615*6777b538SAndroid Build Coastguard Worker explicit Dict(const flat_map<std::string, std::unique_ptr<Value>>& storage); 616*6777b538SAndroid Build Coastguard Worker 617*6777b538SAndroid Build Coastguard Worker // TODO(dcheng): Replace with `flat_map<std::string, Value>` once no caller 618*6777b538SAndroid Build Coastguard Worker // relies on stability of pointers anymore. 619*6777b538SAndroid Build Coastguard Worker flat_map<std::string, std::unique_ptr<Value>> storage_; 620*6777b538SAndroid Build Coastguard Worker }; 621*6777b538SAndroid Build Coastguard Worker 622*6777b538SAndroid Build Coastguard Worker // Represents a list of Values. 623*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT GSL_OWNER List { 624*6777b538SAndroid Build Coastguard Worker public: 625*6777b538SAndroid Build Coastguard Worker using iterator = CheckedContiguousIterator<Value>; 626*6777b538SAndroid Build Coastguard Worker using const_iterator = CheckedContiguousConstIterator<Value>; 627*6777b538SAndroid Build Coastguard Worker using reverse_iterator = std::reverse_iterator<iterator>; 628*6777b538SAndroid Build Coastguard Worker using const_reverse_iterator = std::reverse_iterator<const_iterator>; 629*6777b538SAndroid Build Coastguard Worker using value_type = Value; 630*6777b538SAndroid Build Coastguard Worker 631*6777b538SAndroid Build Coastguard Worker // Creates a list with the given capacity reserved. 632*6777b538SAndroid Build Coastguard Worker // Correctly using this will greatly reduce the code size and improve 633*6777b538SAndroid Build Coastguard Worker // performance when creating a list whose size is known up front. 634*6777b538SAndroid Build Coastguard Worker static List with_capacity(size_t capacity); 635*6777b538SAndroid Build Coastguard Worker 636*6777b538SAndroid Build Coastguard Worker List(); 637*6777b538SAndroid Build Coastguard Worker 638*6777b538SAndroid Build Coastguard Worker List(List&&) noexcept; 639*6777b538SAndroid Build Coastguard Worker List& operator=(List&&) noexcept; 640*6777b538SAndroid Build Coastguard Worker 641*6777b538SAndroid Build Coastguard Worker // Deleted to prevent accidental copying. 642*6777b538SAndroid Build Coastguard Worker List(const List&) = delete; 643*6777b538SAndroid Build Coastguard Worker List& operator=(const List&) = delete; 644*6777b538SAndroid Build Coastguard Worker 645*6777b538SAndroid Build Coastguard Worker ~List(); 646*6777b538SAndroid Build Coastguard Worker 647*6777b538SAndroid Build Coastguard Worker // Returns true if there are no values in this list and false otherwise. 648*6777b538SAndroid Build Coastguard Worker bool empty() const; 649*6777b538SAndroid Build Coastguard Worker 650*6777b538SAndroid Build Coastguard Worker // Returns the number of values in this list. 651*6777b538SAndroid Build Coastguard Worker size_t size() const; 652*6777b538SAndroid Build Coastguard Worker 653*6777b538SAndroid Build Coastguard Worker // Returns an iterator to the first value in this list. 654*6777b538SAndroid Build Coastguard Worker iterator begin(); 655*6777b538SAndroid Build Coastguard Worker const_iterator begin() const; 656*6777b538SAndroid Build Coastguard Worker const_iterator cbegin() const; 657*6777b538SAndroid Build Coastguard Worker 658*6777b538SAndroid Build Coastguard Worker // Returns an iterator following the last value in this list. May not be 659*6777b538SAndroid Build Coastguard Worker // dereferenced. 660*6777b538SAndroid Build Coastguard Worker iterator end(); 661*6777b538SAndroid Build Coastguard Worker const_iterator end() const; 662*6777b538SAndroid Build Coastguard Worker const_iterator cend() const; 663*6777b538SAndroid Build Coastguard Worker 664*6777b538SAndroid Build Coastguard Worker // Returns a reverse iterator preceding the first value in this list. May 665*6777b538SAndroid Build Coastguard Worker // not be dereferenced. 666*6777b538SAndroid Build Coastguard Worker reverse_iterator rend(); 667*6777b538SAndroid Build Coastguard Worker const_reverse_iterator rend() const; 668*6777b538SAndroid Build Coastguard Worker 669*6777b538SAndroid Build Coastguard Worker // Returns a reverse iterator to the last value in this list. 670*6777b538SAndroid Build Coastguard Worker reverse_iterator rbegin(); 671*6777b538SAndroid Build Coastguard Worker const_reverse_iterator rbegin() const; 672*6777b538SAndroid Build Coastguard Worker 673*6777b538SAndroid Build Coastguard Worker // Returns a reference to the first value in the container. Fails with 674*6777b538SAndroid Build Coastguard Worker // `CHECK()` if the list is empty. 675*6777b538SAndroid Build Coastguard Worker const Value& front() const; 676*6777b538SAndroid Build Coastguard Worker Value& front(); 677*6777b538SAndroid Build Coastguard Worker 678*6777b538SAndroid Build Coastguard Worker // Returns a reference to the last value in the container. Fails with 679*6777b538SAndroid Build Coastguard Worker // `CHECK()` if the list is empty. 680*6777b538SAndroid Build Coastguard Worker const Value& back() const; 681*6777b538SAndroid Build Coastguard Worker Value& back(); 682*6777b538SAndroid Build Coastguard Worker 683*6777b538SAndroid Build Coastguard Worker // Increase the capacity of the backing container, but does not change 684*6777b538SAndroid Build Coastguard Worker // the size. Assume all existing iterators will be invalidated. 685*6777b538SAndroid Build Coastguard Worker void reserve(size_t capacity); 686*6777b538SAndroid Build Coastguard Worker 687*6777b538SAndroid Build Coastguard Worker // Resizes the list. 688*6777b538SAndroid Build Coastguard Worker // If `new_size` is greater than current size, the extra elements in the 689*6777b538SAndroid Build Coastguard Worker // back will be destroyed. 690*6777b538SAndroid Build Coastguard Worker // If `new_size` is less than current size, new default-initialized elements 691*6777b538SAndroid Build Coastguard Worker // will be added to the back. 692*6777b538SAndroid Build Coastguard Worker // Assume all existing iterators will be invalidated. 693*6777b538SAndroid Build Coastguard Worker void resize(size_t new_size); 694*6777b538SAndroid Build Coastguard Worker 695*6777b538SAndroid Build Coastguard Worker // Returns a reference to the value at `index` in this list. Fails with a 696*6777b538SAndroid Build Coastguard Worker // `CHECK()` if `index >= size()`. 697*6777b538SAndroid Build Coastguard Worker const Value& operator[](size_t index) const; 698*6777b538SAndroid Build Coastguard Worker Value& operator[](size_t index); 699*6777b538SAndroid Build Coastguard Worker 700*6777b538SAndroid Build Coastguard Worker // Removes all value from this list. 701*6777b538SAndroid Build Coastguard Worker REINITIALIZES_AFTER_MOVE void clear(); 702*6777b538SAndroid Build Coastguard Worker 703*6777b538SAndroid Build Coastguard Worker // Removes the value referenced by `pos` in this list and returns an 704*6777b538SAndroid Build Coastguard Worker // iterator to the value following the removed value. 705*6777b538SAndroid Build Coastguard Worker iterator erase(iterator pos); 706*6777b538SAndroid Build Coastguard Worker const_iterator erase(const_iterator pos); 707*6777b538SAndroid Build Coastguard Worker 708*6777b538SAndroid Build Coastguard Worker // Remove the values in the range [`first`, `last`). Returns iterator to the 709*6777b538SAndroid Build Coastguard Worker // first value following the removed range, which is `last`. If `first` == 710*6777b538SAndroid Build Coastguard Worker // `last`, removes nothing and returns `last`. 711*6777b538SAndroid Build Coastguard Worker iterator erase(iterator first, iterator last); 712*6777b538SAndroid Build Coastguard Worker const_iterator erase(const_iterator first, const_iterator last); 713*6777b538SAndroid Build Coastguard Worker 714*6777b538SAndroid Build Coastguard Worker // Creates a deep copy of this dictionary. 715*6777b538SAndroid Build Coastguard Worker List Clone() const; 716*6777b538SAndroid Build Coastguard Worker 717*6777b538SAndroid Build Coastguard Worker // Appends `value` to the end of this list. 718*6777b538SAndroid Build Coastguard Worker void Append(Value&& value) &; 719*6777b538SAndroid Build Coastguard Worker void Append(bool value) &; 720*6777b538SAndroid Build Coastguard Worker template <typename T> 721*6777b538SAndroid Build Coastguard Worker void Append(const T*) & = delete; 722*6777b538SAndroid Build Coastguard Worker void Append(int value) &; 723*6777b538SAndroid Build Coastguard Worker void Append(double value) &; 724*6777b538SAndroid Build Coastguard Worker void Append(StringPiece value) &; 725*6777b538SAndroid Build Coastguard Worker void Append(StringPiece16 value) &; 726*6777b538SAndroid Build Coastguard Worker void Append(const char* value) &; 727*6777b538SAndroid Build Coastguard Worker void Append(const char16_t* value) &; 728*6777b538SAndroid Build Coastguard Worker void Append(std::string&& value) &; 729*6777b538SAndroid Build Coastguard Worker void Append(BlobStorage&& value) &; 730*6777b538SAndroid Build Coastguard Worker void Append(Dict&& value) &; 731*6777b538SAndroid Build Coastguard Worker void Append(List&& value) &; 732*6777b538SAndroid Build Coastguard Worker 733*6777b538SAndroid Build Coastguard Worker // Rvalue overrides of the `Append` methods, which allow you to construct 734*6777b538SAndroid Build Coastguard Worker // a `Value::List` builder-style: 735*6777b538SAndroid Build Coastguard Worker // 736*6777b538SAndroid Build Coastguard Worker // Value::List result = 737*6777b538SAndroid Build Coastguard Worker // Value::List().Append("first value").Append(2).Append(true); 738*6777b538SAndroid Build Coastguard Worker // 739*6777b538SAndroid Build Coastguard Worker // Each method returns a rvalue reference to `this`, so this is as efficient 740*6777b538SAndroid Build Coastguard Worker // as stand-alone calls to `Append`, while at the same time making it harder 741*6777b538SAndroid Build Coastguard Worker // to accidentally append to the wrong list. 742*6777b538SAndroid Build Coastguard Worker // 743*6777b538SAndroid Build Coastguard Worker // The equivalent code without using these builder-style methods: 744*6777b538SAndroid Build Coastguard Worker // 745*6777b538SAndroid Build Coastguard Worker // Value::List no_builder_example; 746*6777b538SAndroid Build Coastguard Worker // no_builder_example.Append("first value"); 747*6777b538SAndroid Build Coastguard Worker // no_builder_example.Append(2); 748*6777b538SAndroid Build Coastguard Worker // no_builder_example.Append(true); 749*6777b538SAndroid Build Coastguard Worker // 750*6777b538SAndroid Build Coastguard Worker List&& Append(Value&& value) &&; 751*6777b538SAndroid Build Coastguard Worker List&& Append(bool value) &&; 752*6777b538SAndroid Build Coastguard Worker template <typename T> 753*6777b538SAndroid Build Coastguard Worker List&& Append(const T*) && = delete; 754*6777b538SAndroid Build Coastguard Worker List&& Append(int value) &&; 755*6777b538SAndroid Build Coastguard Worker List&& Append(double value) &&; 756*6777b538SAndroid Build Coastguard Worker List&& Append(StringPiece value) &&; 757*6777b538SAndroid Build Coastguard Worker List&& Append(StringPiece16 value) &&; 758*6777b538SAndroid Build Coastguard Worker List&& Append(const char* value) &&; 759*6777b538SAndroid Build Coastguard Worker List&& Append(const char16_t* value) &&; 760*6777b538SAndroid Build Coastguard Worker List&& Append(std::string&& value) &&; 761*6777b538SAndroid Build Coastguard Worker List&& Append(BlobStorage&& value) &&; 762*6777b538SAndroid Build Coastguard Worker List&& Append(Dict&& value) &&; 763*6777b538SAndroid Build Coastguard Worker List&& Append(List&& value) &&; 764*6777b538SAndroid Build Coastguard Worker 765*6777b538SAndroid Build Coastguard Worker // Inserts `value` before `pos` in this list. Returns an iterator to the 766*6777b538SAndroid Build Coastguard Worker // inserted value. 767*6777b538SAndroid Build Coastguard Worker // TODO(dcheng): Should this provide the same set of overloads that Append() 768*6777b538SAndroid Build Coastguard Worker // does? 769*6777b538SAndroid Build Coastguard Worker iterator Insert(const_iterator pos, Value&& value); 770*6777b538SAndroid Build Coastguard Worker 771*6777b538SAndroid Build Coastguard Worker // Erases all values equal to `value` from this list. 772*6777b538SAndroid Build Coastguard Worker size_t EraseValue(const Value& value); 773*6777b538SAndroid Build Coastguard Worker 774*6777b538SAndroid Build Coastguard Worker // Erases all values for which `predicate` evaluates to true from this list. 775*6777b538SAndroid Build Coastguard Worker template <typename Predicate> EraseIf(Predicate predicate)776*6777b538SAndroid Build Coastguard Worker size_t EraseIf(Predicate predicate) { 777*6777b538SAndroid Build Coastguard Worker return std::erase_if(storage_, predicate); 778*6777b538SAndroid Build Coastguard Worker } 779*6777b538SAndroid Build Coastguard Worker 780*6777b538SAndroid Build Coastguard Worker // Estimates dynamic memory usage. Requires tracing support 781*6777b538SAndroid Build Coastguard Worker // (enable_base_tracing gn flag), otherwise always returns 0. See 782*6777b538SAndroid Build Coastguard Worker // base/trace_event/memory_usage_estimator.h for more info. 783*6777b538SAndroid Build Coastguard Worker size_t EstimateMemoryUsage() const; 784*6777b538SAndroid Build Coastguard Worker 785*6777b538SAndroid Build Coastguard Worker // Serializes to a string for logging and debug purposes. 786*6777b538SAndroid Build Coastguard Worker std::string DebugString() const; 787*6777b538SAndroid Build Coastguard Worker 788*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BASE_TRACING) 789*6777b538SAndroid Build Coastguard Worker // Write this object into a trace. 790*6777b538SAndroid Build Coastguard Worker void WriteIntoTrace(perfetto::TracedValue) const; 791*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(ENABLE_BASE_TRACING) 792*6777b538SAndroid Build Coastguard Worker 793*6777b538SAndroid Build Coastguard Worker private: 794*6777b538SAndroid Build Coastguard Worker using ListStorage = std::vector<Value>; 795*6777b538SAndroid Build Coastguard Worker 796*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const List& lhs, const List& rhs); 797*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator!=(const List& lhs, const List& rhs); 798*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator<(const List& lhs, const List& rhs); 799*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator>(const List& lhs, const List& rhs); 800*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator<=(const List& lhs, const List& rhs); 801*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator>=(const List& lhs, const List& rhs); 802*6777b538SAndroid Build Coastguard Worker 803*6777b538SAndroid Build Coastguard Worker explicit List(const std::vector<Value>& storage); 804*6777b538SAndroid Build Coastguard Worker 805*6777b538SAndroid Build Coastguard Worker std::vector<Value> storage_; 806*6777b538SAndroid Build Coastguard Worker }; 807*6777b538SAndroid Build Coastguard Worker 808*6777b538SAndroid Build Coastguard Worker // Note: Do not add more types. See the file-level comment above for why. 809*6777b538SAndroid Build Coastguard Worker 810*6777b538SAndroid Build Coastguard Worker // Comparison operators so that Values can easily be used with standard 811*6777b538SAndroid Build Coastguard Worker // library algorithms and associative containers. 812*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const Value& lhs, const Value& rhs); 813*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator!=(const Value& lhs, const Value& rhs); 814*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator<(const Value& lhs, const Value& rhs); 815*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator>(const Value& lhs, const Value& rhs); 816*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator<=(const Value& lhs, const Value& rhs); 817*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator>=(const Value& lhs, const Value& rhs); 818*6777b538SAndroid Build Coastguard Worker 819*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const Value& lhs, bool rhs); 820*6777b538SAndroid Build Coastguard Worker friend bool operator==(bool lhs, const Value& rhs) { return rhs == lhs; } 821*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value& lhs, bool rhs) { return !(lhs == rhs); } 822*6777b538SAndroid Build Coastguard Worker friend bool operator!=(bool lhs, const Value& rhs) { return !(lhs == rhs); } 823*6777b538SAndroid Build Coastguard Worker template <typename T> 824*6777b538SAndroid Build Coastguard Worker friend bool operator==(const Value& lhs, const T* rhs) = delete; 825*6777b538SAndroid Build Coastguard Worker template <typename T> 826*6777b538SAndroid Build Coastguard Worker friend bool operator==(const T* lhs, const Value& rhs) = delete; 827*6777b538SAndroid Build Coastguard Worker template <typename T> 828*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value& lhs, const T* rhs) = delete; 829*6777b538SAndroid Build Coastguard Worker template <typename T> 830*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const T* lhs, const Value& rhs) = delete; 831*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const Value& lhs, int rhs); 832*6777b538SAndroid Build Coastguard Worker friend bool operator==(int lhs, const Value& rhs) { return rhs == lhs; } 833*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value& lhs, int rhs) { return !(lhs == rhs); } 834*6777b538SAndroid Build Coastguard Worker friend bool operator!=(int lhs, const Value& rhs) { return !(lhs == rhs); } 835*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const Value& lhs, double rhs); 836*6777b538SAndroid Build Coastguard Worker friend bool operator==(double lhs, const Value& rhs) { return rhs == lhs; } 837*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value& lhs, double rhs) { return !(lhs == rhs); } 838*6777b538SAndroid Build Coastguard Worker friend bool operator!=(double lhs, const Value& rhs) { return !(lhs == rhs); } 839*6777b538SAndroid Build Coastguard Worker // Note: StringPiece16 overload intentionally omitted: Value internally stores 840*6777b538SAndroid Build Coastguard Worker // strings as UTF-8. While it is possible to implement a comparison operator 841*6777b538SAndroid Build Coastguard Worker // that would not require first creating a new UTF-8 string from the UTF-16 842*6777b538SAndroid Build Coastguard Worker // string argument, it is simpler to just not implement it at all for a rare 843*6777b538SAndroid Build Coastguard Worker // use case. 844*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const Value& lhs, StringPiece rhs); 845*6777b538SAndroid Build Coastguard Worker friend bool operator==(StringPiece lhs, const Value& rhs) { 846*6777b538SAndroid Build Coastguard Worker return rhs == lhs; 847*6777b538SAndroid Build Coastguard Worker } 848*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value& lhs, StringPiece rhs) { 849*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 850*6777b538SAndroid Build Coastguard Worker } 851*6777b538SAndroid Build Coastguard Worker friend bool operator!=(StringPiece lhs, const Value& rhs) { 852*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 853*6777b538SAndroid Build Coastguard Worker } 854*6777b538SAndroid Build Coastguard Worker friend bool operator==(const Value& lhs, const char* rhs) { 855*6777b538SAndroid Build Coastguard Worker return lhs == StringPiece(rhs); 856*6777b538SAndroid Build Coastguard Worker } 857*6777b538SAndroid Build Coastguard Worker friend bool operator==(const char* lhs, const Value& rhs) { 858*6777b538SAndroid Build Coastguard Worker return rhs == lhs; 859*6777b538SAndroid Build Coastguard Worker } 860*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value& lhs, const char* rhs) { 861*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 862*6777b538SAndroid Build Coastguard Worker } 863*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const char* lhs, const Value& rhs) { 864*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 865*6777b538SAndroid Build Coastguard Worker } 866*6777b538SAndroid Build Coastguard Worker friend bool operator==(const Value& lhs, const std::string& rhs) { 867*6777b538SAndroid Build Coastguard Worker return lhs == StringPiece(rhs); 868*6777b538SAndroid Build Coastguard Worker } 869*6777b538SAndroid Build Coastguard Worker friend bool operator==(const std::string& lhs, const Value& rhs) { 870*6777b538SAndroid Build Coastguard Worker return rhs == lhs; 871*6777b538SAndroid Build Coastguard Worker } 872*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value& lhs, const std::string& rhs) { 873*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 874*6777b538SAndroid Build Coastguard Worker } 875*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const std::string& lhs, const Value& rhs) { 876*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 877*6777b538SAndroid Build Coastguard Worker } 878*6777b538SAndroid Build Coastguard Worker // Note: Blob support intentionally omitted as an experiment for potentially 879*6777b538SAndroid Build Coastguard Worker // wholly removing Blob support from Value itself in the future. 880*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const Value& lhs, const Value::Dict& rhs); 881*6777b538SAndroid Build Coastguard Worker friend bool operator==(const Value::Dict& lhs, const Value& rhs) { 882*6777b538SAndroid Build Coastguard Worker return rhs == lhs; 883*6777b538SAndroid Build Coastguard Worker } 884*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value& lhs, const Value::Dict& rhs) { 885*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 886*6777b538SAndroid Build Coastguard Worker } 887*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value::Dict& lhs, const Value& rhs) { 888*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 889*6777b538SAndroid Build Coastguard Worker } 890*6777b538SAndroid Build Coastguard Worker BASE_EXPORT friend bool operator==(const Value& lhs, const Value::List& rhs); 891*6777b538SAndroid Build Coastguard Worker friend bool operator==(const Value::List& lhs, const Value& rhs) { 892*6777b538SAndroid Build Coastguard Worker return rhs == lhs; 893*6777b538SAndroid Build Coastguard Worker } 894*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value& lhs, const Value::List& rhs) { 895*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 896*6777b538SAndroid Build Coastguard Worker } 897*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const Value::List& lhs, const Value& rhs) { 898*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 899*6777b538SAndroid Build Coastguard Worker } 900*6777b538SAndroid Build Coastguard Worker 901*6777b538SAndroid Build Coastguard Worker // Estimates dynamic memory usage. Requires tracing support 902*6777b538SAndroid Build Coastguard Worker // (enable_base_tracing gn flag), otherwise always returns 0. See 903*6777b538SAndroid Build Coastguard Worker // base/trace_event/memory_usage_estimator.h for more info. 904*6777b538SAndroid Build Coastguard Worker size_t EstimateMemoryUsage() const; 905*6777b538SAndroid Build Coastguard Worker 906*6777b538SAndroid Build Coastguard Worker // Serializes to a string for logging and debug purposes. 907*6777b538SAndroid Build Coastguard Worker std::string DebugString() const; 908*6777b538SAndroid Build Coastguard Worker 909*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(ENABLE_BASE_TRACING) 910*6777b538SAndroid Build Coastguard Worker // Write this object into a trace. 911*6777b538SAndroid Build Coastguard Worker void WriteIntoTrace(perfetto::TracedValue) const; 912*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(ENABLE_BASE_TRACING) 913*6777b538SAndroid Build Coastguard Worker 914*6777b538SAndroid Build Coastguard Worker template <typename Visitor> Visit(Visitor && visitor)915*6777b538SAndroid Build Coastguard Worker auto Visit(Visitor&& visitor) const { 916*6777b538SAndroid Build Coastguard Worker return absl::visit(std::forward<Visitor>(visitor), data_); 917*6777b538SAndroid Build Coastguard Worker } 918*6777b538SAndroid Build Coastguard Worker 919*6777b538SAndroid Build Coastguard Worker private: 920*6777b538SAndroid Build Coastguard Worker // For access to DoubleStorage. 921*6777b538SAndroid Build Coastguard Worker friend class ValueView; 922*6777b538SAndroid Build Coastguard Worker 923*6777b538SAndroid Build Coastguard Worker // Special case for doubles, which are aligned to 8 bytes on some 924*6777b538SAndroid Build Coastguard Worker // 32-bit architectures. In this case, a simple declaration as a 925*6777b538SAndroid Build Coastguard Worker // double member would make the whole union 8 byte-aligned, which 926*6777b538SAndroid Build Coastguard Worker // would also force 4 bytes of wasted padding space before it in 927*6777b538SAndroid Build Coastguard Worker // the Value layout. 928*6777b538SAndroid Build Coastguard Worker // 929*6777b538SAndroid Build Coastguard Worker // To override this, store the value as an array of 32-bit integers, and 930*6777b538SAndroid Build Coastguard Worker // perform the appropriate bit casts when reading / writing to it. 931*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT DoubleStorage { 932*6777b538SAndroid Build Coastguard Worker public: 933*6777b538SAndroid Build Coastguard Worker explicit DoubleStorage(double v); 934*6777b538SAndroid Build Coastguard Worker DoubleStorage(const DoubleStorage&) = default; 935*6777b538SAndroid Build Coastguard Worker DoubleStorage& operator=(const DoubleStorage&) = default; 936*6777b538SAndroid Build Coastguard Worker 937*6777b538SAndroid Build Coastguard Worker // Provide an implicit conversion to double to simplify the use of visitors 938*6777b538SAndroid Build Coastguard Worker // with `Value::Visit()`. Otherwise, visitors would need a branch for 939*6777b538SAndroid Build Coastguard Worker // handling `DoubleStorage` like: 940*6777b538SAndroid Build Coastguard Worker // 941*6777b538SAndroid Build Coastguard Worker // value.Visit([] (const auto& member) { 942*6777b538SAndroid Build Coastguard Worker // using T = std::decay_t<decltype(member)>; 943*6777b538SAndroid Build Coastguard Worker // if constexpr (std::is_same_v<T, Value::DoubleStorage>) { 944*6777b538SAndroid Build Coastguard Worker // SomeFunction(double{member}); 945*6777b538SAndroid Build Coastguard Worker // } else { 946*6777b538SAndroid Build Coastguard Worker // SomeFunction(member); 947*6777b538SAndroid Build Coastguard Worker // } 948*6777b538SAndroid Build Coastguard Worker // }); 949*6777b538SAndroid Build Coastguard Worker operator double() const { return base::bit_cast<double>(v_); } 950*6777b538SAndroid Build Coastguard Worker 951*6777b538SAndroid Build Coastguard Worker private: 952*6777b538SAndroid Build Coastguard Worker friend bool operator==(const DoubleStorage& lhs, const DoubleStorage& rhs) { 953*6777b538SAndroid Build Coastguard Worker return double{lhs} == double{rhs}; 954*6777b538SAndroid Build Coastguard Worker } 955*6777b538SAndroid Build Coastguard Worker 956*6777b538SAndroid Build Coastguard Worker friend bool operator!=(const DoubleStorage& lhs, const DoubleStorage& rhs) { 957*6777b538SAndroid Build Coastguard Worker return !(lhs == rhs); 958*6777b538SAndroid Build Coastguard Worker } 959*6777b538SAndroid Build Coastguard Worker 960*6777b538SAndroid Build Coastguard Worker friend bool operator<(const DoubleStorage& lhs, const DoubleStorage& rhs) { 961*6777b538SAndroid Build Coastguard Worker return double{lhs} < double{rhs}; 962*6777b538SAndroid Build Coastguard Worker } 963*6777b538SAndroid Build Coastguard Worker 964*6777b538SAndroid Build Coastguard Worker friend bool operator>(const DoubleStorage& lhs, const DoubleStorage& rhs) { 965*6777b538SAndroid Build Coastguard Worker return rhs < lhs; 966*6777b538SAndroid Build Coastguard Worker } 967*6777b538SAndroid Build Coastguard Worker 968*6777b538SAndroid Build Coastguard Worker friend bool operator<=(const DoubleStorage& lhs, const DoubleStorage& rhs) { 969*6777b538SAndroid Build Coastguard Worker return !(rhs < lhs); 970*6777b538SAndroid Build Coastguard Worker } 971*6777b538SAndroid Build Coastguard Worker 972*6777b538SAndroid Build Coastguard Worker friend bool operator>=(const DoubleStorage& lhs, const DoubleStorage& rhs) { 973*6777b538SAndroid Build Coastguard Worker return !(lhs < rhs); 974*6777b538SAndroid Build Coastguard Worker } 975*6777b538SAndroid Build Coastguard Worker 976*6777b538SAndroid Build Coastguard Worker alignas(4) std::array<char, sizeof(double)> v_; 977*6777b538SAndroid Build Coastguard Worker }; 978*6777b538SAndroid Build Coastguard Worker 979*6777b538SAndroid Build Coastguard Worker // Internal constructors, allowing the simplify the implementation of Clone(). 980*6777b538SAndroid Build Coastguard Worker explicit Value(absl::monostate); 981*6777b538SAndroid Build Coastguard Worker explicit Value(DoubleStorage storage); 982*6777b538SAndroid Build Coastguard Worker 983*6777b538SAndroid Build Coastguard Worker // A helper for static functions used for cloning a Value or a ValueView. 984*6777b538SAndroid Build Coastguard Worker class CloningHelper; 985*6777b538SAndroid Build Coastguard Worker 986*6777b538SAndroid Build Coastguard Worker absl::variant<absl::monostate, 987*6777b538SAndroid Build Coastguard Worker bool, 988*6777b538SAndroid Build Coastguard Worker int, 989*6777b538SAndroid Build Coastguard Worker DoubleStorage, 990*6777b538SAndroid Build Coastguard Worker std::string, 991*6777b538SAndroid Build Coastguard Worker BlobStorage, 992*6777b538SAndroid Build Coastguard Worker Dict, 993*6777b538SAndroid Build Coastguard Worker List> 994*6777b538SAndroid Build Coastguard Worker data_; 995*6777b538SAndroid Build Coastguard Worker }; 996*6777b538SAndroid Build Coastguard Worker 997*6777b538SAndroid Build Coastguard Worker // Adapter so `Value::Dict` or `Value::List` can be directly passed to JSON 998*6777b538SAndroid Build Coastguard Worker // serialization methods without having to clone the contents and transfer 999*6777b538SAndroid Build Coastguard Worker // ownership of the clone to a `Value` wrapper object. 1000*6777b538SAndroid Build Coastguard Worker // 1001*6777b538SAndroid Build Coastguard Worker // Like `StringPiece` and `span<T>`, this adapter does NOT retain ownership. Any 1002*6777b538SAndroid Build Coastguard Worker // underlying object that is passed by reference (i.e. `std::string`, 1003*6777b538SAndroid Build Coastguard Worker // `Value::BlobStorage`, `Value::Dict`, `Value::List`, or `Value`) MUST remain 1004*6777b538SAndroid Build Coastguard Worker // live as long as there is a `ValueView` referencing it. 1005*6777b538SAndroid Build Coastguard Worker // 1006*6777b538SAndroid Build Coastguard Worker // While it might be nice to just use the `absl::variant` type directly, the 1007*6777b538SAndroid Build Coastguard Worker // need to use `std::reference_wrapper` makes it clunky. `absl::variant` and 1008*6777b538SAndroid Build Coastguard Worker // `std::reference_wrapper` both support implicit construction, but C++ only 1009*6777b538SAndroid Build Coastguard Worker // allows at most one user-defined conversion in an implicit conversion 1010*6777b538SAndroid Build Coastguard Worker // sequence. If this adapter and its implicit constructors did not exist, 1011*6777b538SAndroid Build Coastguard Worker // callers would need to use `std::ref` or `std::cref` to pass `Value::Dict` or 1012*6777b538SAndroid Build Coastguard Worker // `Value::List` to a function with a `ValueView` parameter. 1013*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT GSL_POINTER ValueView { 1014*6777b538SAndroid Build Coastguard Worker public: 1015*6777b538SAndroid Build Coastguard Worker ValueView() = default; ValueView(bool value)1016*6777b538SAndroid Build Coastguard Worker ValueView(bool value) : data_view_(value) {} 1017*6777b538SAndroid Build Coastguard Worker template <typename T> 1018*6777b538SAndroid Build Coastguard Worker ValueView(const T*) = delete; ValueView(int value)1019*6777b538SAndroid Build Coastguard Worker ValueView(int value) : data_view_(value) {} ValueView(double value)1020*6777b538SAndroid Build Coastguard Worker ValueView(double value) 1021*6777b538SAndroid Build Coastguard Worker : data_view_(absl::in_place_type_t<Value::DoubleStorage>(), value) {} ValueView(StringPiece value)1022*6777b538SAndroid Build Coastguard Worker ValueView(StringPiece value) : data_view_(value) {} ValueView(const char * value)1023*6777b538SAndroid Build Coastguard Worker ValueView(const char* value) : ValueView(StringPiece(value)) {} ValueView(const std::string & value)1024*6777b538SAndroid Build Coastguard Worker ValueView(const std::string& value) : ValueView(StringPiece(value)) {} 1025*6777b538SAndroid Build Coastguard Worker // Note: UTF-16 is intentionally not supported. ValueView is intended to be a 1026*6777b538SAndroid Build Coastguard Worker // low-cost view abstraction, but Value internally represents strings as 1027*6777b538SAndroid Build Coastguard Worker // UTF-8, so it would not be possible to implement this without allocating an 1028*6777b538SAndroid Build Coastguard Worker // entirely new UTF-8 string. ValueView(const Value::BlobStorage & value)1029*6777b538SAndroid Build Coastguard Worker ValueView(const Value::BlobStorage& value) : data_view_(value) {} ValueView(const Value::Dict & value)1030*6777b538SAndroid Build Coastguard Worker ValueView(const Value::Dict& value) : data_view_(value) {} ValueView(const Value::List & value)1031*6777b538SAndroid Build Coastguard Worker ValueView(const Value::List& value) : data_view_(value) {} 1032*6777b538SAndroid Build Coastguard Worker ValueView(const Value& value); 1033*6777b538SAndroid Build Coastguard Worker 1034*6777b538SAndroid Build Coastguard Worker // This is the only 'getter' method provided as `ValueView` is not intended 1035*6777b538SAndroid Build Coastguard Worker // to be a general replacement of `Value`. 1036*6777b538SAndroid Build Coastguard Worker template <typename Visitor> Visit(Visitor && visitor)1037*6777b538SAndroid Build Coastguard Worker auto Visit(Visitor&& visitor) const { 1038*6777b538SAndroid Build Coastguard Worker return absl::visit(std::forward<Visitor>(visitor), data_view_); 1039*6777b538SAndroid Build Coastguard Worker } 1040*6777b538SAndroid Build Coastguard Worker 1041*6777b538SAndroid Build Coastguard Worker // Returns a clone of the underlying Value. 1042*6777b538SAndroid Build Coastguard Worker Value ToValue() const; 1043*6777b538SAndroid Build Coastguard Worker 1044*6777b538SAndroid Build Coastguard Worker private: 1045*6777b538SAndroid Build Coastguard Worker using ViewType = 1046*6777b538SAndroid Build Coastguard Worker absl::variant<absl::monostate, 1047*6777b538SAndroid Build Coastguard Worker bool, 1048*6777b538SAndroid Build Coastguard Worker int, 1049*6777b538SAndroid Build Coastguard Worker Value::DoubleStorage, 1050*6777b538SAndroid Build Coastguard Worker StringPiece, 1051*6777b538SAndroid Build Coastguard Worker std::reference_wrapper<const Value::BlobStorage>, 1052*6777b538SAndroid Build Coastguard Worker std::reference_wrapper<const Value::Dict>, 1053*6777b538SAndroid Build Coastguard Worker std::reference_wrapper<const Value::List>>; 1054*6777b538SAndroid Build Coastguard Worker 1055*6777b538SAndroid Build Coastguard Worker public: 1056*6777b538SAndroid Build Coastguard Worker using DoubleStorageForTest = Value::DoubleStorage; data_view_for_test()1057*6777b538SAndroid Build Coastguard Worker const ViewType& data_view_for_test() const { return data_view_; } 1058*6777b538SAndroid Build Coastguard Worker 1059*6777b538SAndroid Build Coastguard Worker private: 1060*6777b538SAndroid Build Coastguard Worker ViewType data_view_; 1061*6777b538SAndroid Build Coastguard Worker }; 1062*6777b538SAndroid Build Coastguard Worker 1063*6777b538SAndroid Build Coastguard Worker // This interface is implemented by classes that know how to serialize 1064*6777b538SAndroid Build Coastguard Worker // Value objects. 1065*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ValueSerializer { 1066*6777b538SAndroid Build Coastguard Worker public: 1067*6777b538SAndroid Build Coastguard Worker virtual ~ValueSerializer(); 1068*6777b538SAndroid Build Coastguard Worker 1069*6777b538SAndroid Build Coastguard Worker virtual bool Serialize(ValueView root) = 0; 1070*6777b538SAndroid Build Coastguard Worker }; 1071*6777b538SAndroid Build Coastguard Worker 1072*6777b538SAndroid Build Coastguard Worker // This interface is implemented by classes that know how to deserialize Value 1073*6777b538SAndroid Build Coastguard Worker // objects. 1074*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ValueDeserializer { 1075*6777b538SAndroid Build Coastguard Worker public: 1076*6777b538SAndroid Build Coastguard Worker virtual ~ValueDeserializer(); 1077*6777b538SAndroid Build Coastguard Worker 1078*6777b538SAndroid Build Coastguard Worker // This method deserializes the subclass-specific format into a Value object. 1079*6777b538SAndroid Build Coastguard Worker // If the return value is non-NULL, the caller takes ownership of returned 1080*6777b538SAndroid Build Coastguard Worker // Value. 1081*6777b538SAndroid Build Coastguard Worker // 1082*6777b538SAndroid Build Coastguard Worker // If the return value is nullptr, and if `error_code` is non-nullptr, 1083*6777b538SAndroid Build Coastguard Worker // `*error_code` will be set to an integer value representing the underlying 1084*6777b538SAndroid Build Coastguard Worker // error. See "enum ErrorCode" below for more detail about the integer value. 1085*6777b538SAndroid Build Coastguard Worker // 1086*6777b538SAndroid Build Coastguard Worker // If `error_message` is non-nullptr, it will be filled in with a formatted 1087*6777b538SAndroid Build Coastguard Worker // error message including the location of the error if appropriate. 1088*6777b538SAndroid Build Coastguard Worker virtual std::unique_ptr<Value> Deserialize(int* error_code, 1089*6777b538SAndroid Build Coastguard Worker std::string* error_message) = 0; 1090*6777b538SAndroid Build Coastguard Worker 1091*6777b538SAndroid Build Coastguard Worker // The integer-valued error codes form four groups: 1092*6777b538SAndroid Build Coastguard Worker // - The value 0 means no error. 1093*6777b538SAndroid Build Coastguard Worker // - Values between 1 and 999 inclusive mean an error in the data (i.e. 1094*6777b538SAndroid Build Coastguard Worker // content). The bytes being deserialized are not in the right format. 1095*6777b538SAndroid Build Coastguard Worker // - Values 1000 and above mean an error in the metadata (i.e. context). The 1096*6777b538SAndroid Build Coastguard Worker // file could not be read, the network is down, etc. 1097*6777b538SAndroid Build Coastguard Worker // - Negative values are reserved. 1098*6777b538SAndroid Build Coastguard Worker // 1099*6777b538SAndroid Build Coastguard Worker // These values are persisted to logs. Entries should not be renumbered and 1100*6777b538SAndroid Build Coastguard Worker // numeric values should never be reused. 1101*6777b538SAndroid Build Coastguard Worker enum ErrorCode { 1102*6777b538SAndroid Build Coastguard Worker kErrorCodeNoError = 0, 1103*6777b538SAndroid Build Coastguard Worker // kErrorCodeInvalidFormat is a generic error code for "the data is not in 1104*6777b538SAndroid Build Coastguard Worker // the right format". Subclasses of ValueDeserializer may return other 1105*6777b538SAndroid Build Coastguard Worker // values for more specific errors. 1106*6777b538SAndroid Build Coastguard Worker kErrorCodeInvalidFormat = 1, 1107*6777b538SAndroid Build Coastguard Worker // kErrorCodeFirstMetadataError is the minimum value (inclusive) of the 1108*6777b538SAndroid Build Coastguard Worker // range of metadata errors. 1109*6777b538SAndroid Build Coastguard Worker kErrorCodeFirstMetadataError = 1000, 1110*6777b538SAndroid Build Coastguard Worker }; 1111*6777b538SAndroid Build Coastguard Worker 1112*6777b538SAndroid Build Coastguard Worker // The `error_code` argument can be one of the ErrorCode values, but it is 1113*6777b538SAndroid Build Coastguard Worker // not restricted to only being 0, 1 or 1000. Subclasses of ValueDeserializer 1114*6777b538SAndroid Build Coastguard Worker // can define their own error code values. ErrorCodeIsDataError(int error_code)1115*6777b538SAndroid Build Coastguard Worker static inline bool ErrorCodeIsDataError(int error_code) { 1116*6777b538SAndroid Build Coastguard Worker return (kErrorCodeInvalidFormat <= error_code) && 1117*6777b538SAndroid Build Coastguard Worker (error_code < kErrorCodeFirstMetadataError); 1118*6777b538SAndroid Build Coastguard Worker } 1119*6777b538SAndroid Build Coastguard Worker }; 1120*6777b538SAndroid Build Coastguard Worker 1121*6777b538SAndroid Build Coastguard Worker // Stream operator so Values can be pretty printed by gtest. 1122*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& out, const Value& value); 1123*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& out, 1124*6777b538SAndroid Build Coastguard Worker const Value::Dict& dict); 1125*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& out, 1126*6777b538SAndroid Build Coastguard Worker const Value::List& list); 1127*6777b538SAndroid Build Coastguard Worker 1128*6777b538SAndroid Build Coastguard Worker // Stream operator so that enum class Types can be used in log statements. 1129*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& out, 1130*6777b538SAndroid Build Coastguard Worker const Value::Type& type); 1131*6777b538SAndroid Build Coastguard Worker 1132*6777b538SAndroid Build Coastguard Worker } // namespace base 1133*6777b538SAndroid Build Coastguard Worker 1134*6777b538SAndroid Build Coastguard Worker #endif // BASE_VALUES_H_ 1135