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