values.cc 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/values.h"
  5. #include <algorithm>
  6. #include <cmath>
  7. #include <ostream>
  8. #include <tuple>
  9. #include <utility>
  10. #include "base/as_const.h"
  11. #include "base/bit_cast.h"
  12. #include "base/check.h"
  13. #include "base/check_op.h"
  14. #include "base/containers/checked_iterators.h"
  15. #include "base/containers/cxx20_erase_vector.h"
  16. #include "base/cxx17_backports.h"
  17. #include "base/cxx20_to_address.h"
  18. #include "base/json/json_writer.h"
  19. #include "base/logging.h"
  20. #include "base/memory/ptr_util.h"
  21. #include "base/notreached.h"
  22. #include "base/ranges/algorithm.h"
  23. #include "base/strings/string_util.h"
  24. #include "base/strings/utf_string_conversions.h"
  25. #include "base/trace_event/base_tracing.h"
  26. #include "base/tracing_buildflags.h"
  27. #include "third_party/abseil-cpp/absl/types/optional.h"
  28. #include "third_party/abseil-cpp/absl/types/variant.h"
  29. #if BUILDFLAG(ENABLE_BASE_TRACING)
  30. #include "base/trace_event/memory_usage_estimator.h" // no-presubmit-check
  31. #endif // BUILDFLAG(ENABLE_BASE_TRACING)
  32. namespace base {
  33. namespace {
  34. const char* const kTypeNames[] = {"null", "boolean", "integer", "double",
  35. "string", "binary", "dictionary", "list"};
  36. static_assert(std::size(kTypeNames) ==
  37. static_cast<size_t>(Value::Type::LIST) + 1,
  38. "kTypeNames Has Wrong Size");
  39. // Helper class to enumerate the path components from a StringPiece
  40. // without performing heap allocations. Components are simply separated
  41. // by single dots (e.g. "foo.bar.baz" -> ["foo", "bar", "baz"]).
  42. //
  43. // Usage example:
  44. // PathSplitter splitter(some_path);
  45. // while (splitter.HasNext()) {
  46. // StringPiece component = splitter.Next();
  47. // ...
  48. // }
  49. //
  50. class PathSplitter {
  51. public:
  52. explicit PathSplitter(StringPiece path) : path_(path) {}
  53. bool HasNext() const { return pos_ < path_.size(); }
  54. StringPiece Next() {
  55. DCHECK(HasNext());
  56. size_t start = pos_;
  57. size_t pos = path_.find('.', start);
  58. size_t end;
  59. if (pos == path_.npos) {
  60. end = path_.size();
  61. pos_ = end;
  62. } else {
  63. end = pos;
  64. pos_ = pos + 1;
  65. }
  66. return path_.substr(start, end - start);
  67. }
  68. private:
  69. StringPiece path_;
  70. size_t pos_ = 0;
  71. };
  72. std::string DebugStringImpl(ValueView value) {
  73. std::string json;
  74. JSONWriter::WriteWithOptions(value, JSONWriter::OPTIONS_PRETTY_PRINT, &json);
  75. return json;
  76. }
  77. } // namespace
  78. // A helper used to provide templated functions for cloning to Value, and
  79. // ValueView. This private class is used so the cloning method may have access
  80. // to the special private constructors in Value, created specifically for
  81. // cloning.
  82. class Value::CloningHelper {
  83. public:
  84. // This set of overloads are used to unwrap the reference wrappers, which are
  85. // presented when cloning a ValueView.
  86. template <typename T>
  87. static const T& UnwrapReference(std::reference_wrapper<const T> value) {
  88. return value.get();
  89. }
  90. template <typename T>
  91. static const T& UnwrapReference(const T& value) {
  92. return value;
  93. }
  94. // Returns a new Value object using the contents of the |storage| variant.
  95. template <typename Storage>
  96. static Value Clone(const Storage& storage) {
  97. return absl::visit(
  98. [](const auto& member) {
  99. const auto& value = UnwrapReference(member);
  100. using T = std::decay_t<decltype(value)>;
  101. if constexpr (std::is_same_v<T, Value::Dict> ||
  102. std::is_same_v<T, Value::List>) {
  103. return Value(value.Clone());
  104. } else {
  105. return Value(value);
  106. }
  107. },
  108. storage);
  109. }
  110. };
  111. // static
  112. Value Value::FromUniquePtrValue(std::unique_ptr<Value> val) {
  113. return std::move(*val);
  114. }
  115. // static
  116. std::unique_ptr<Value> Value::ToUniquePtrValue(Value val) {
  117. return std::make_unique<Value>(std::move(val));
  118. }
  119. // static
  120. const DictionaryValue& Value::AsDictionaryValue(const Value& val) {
  121. CHECK(val.is_dict());
  122. return static_cast<const DictionaryValue&>(val);
  123. }
  124. // static
  125. const ListValue& Value::AsListValue(const Value& val) {
  126. CHECK(val.is_list());
  127. return static_cast<const ListValue&>(val);
  128. }
  129. Value::Value() noexcept = default;
  130. Value::Value(Value&&) noexcept = default;
  131. Value& Value::operator=(Value&&) noexcept = default;
  132. Value::Value(Type type) {
  133. // Initialize with the default value.
  134. switch (type) {
  135. case Type::NONE:
  136. return;
  137. case Type::BOOLEAN:
  138. data_.emplace<bool>(false);
  139. return;
  140. case Type::INTEGER:
  141. data_.emplace<int>(0);
  142. return;
  143. case Type::DOUBLE:
  144. data_.emplace<DoubleStorage>(0.0);
  145. return;
  146. case Type::STRING:
  147. data_.emplace<std::string>();
  148. return;
  149. case Type::BINARY:
  150. data_.emplace<BlobStorage>();
  151. return;
  152. case Type::DICTIONARY:
  153. data_.emplace<Dict>();
  154. return;
  155. case Type::LIST:
  156. data_.emplace<List>();
  157. return;
  158. }
  159. CHECK(false);
  160. }
  161. Value::Value(bool value) : data_(value) {}
  162. Value::Value(int value) : data_(value) {}
  163. Value::Value(double value)
  164. : data_(absl::in_place_type_t<DoubleStorage>(), value) {}
  165. Value::Value(StringPiece value) : Value(std::string(value)) {}
  166. Value::Value(StringPiece16 value) : Value(UTF16ToUTF8(value)) {}
  167. Value::Value(const char* value) : Value(std::string(value)) {}
  168. Value::Value(const char16_t* value) : Value(UTF16ToUTF8(value)) {}
  169. Value::Value(std::string&& value) noexcept : data_(std::move(value)) {
  170. DCHECK(IsStringUTF8AllowingNoncharacters(GetString()));
  171. }
  172. Value::Value(const std::vector<char>& value)
  173. : data_(absl::in_place_type_t<BlobStorage>(), value.begin(), value.end()) {}
  174. Value::Value(base::span<const uint8_t> value)
  175. : data_(absl::in_place_type_t<BlobStorage>(), value.size()) {
  176. // This is 100x faster than using the "range" constructor for a 512k blob:
  177. // crbug.com/1343636
  178. std::copy(value.begin(), value.end(), absl::get<BlobStorage>(data_).data());
  179. }
  180. Value::Value(BlobStorage&& value) noexcept : data_(std::move(value)) {}
  181. Value::Value(Dict&& value) noexcept : data_(std::move(value)) {}
  182. Value::Value(List&& value) noexcept : data_(std::move(value)) {}
  183. Value::Value(const LegacyDictStorage& storage)
  184. : data_(absl::in_place_type_t<Dict>()) {
  185. dict().reserve(storage.size());
  186. for (const auto& it : storage) {
  187. dict().try_emplace(dict().end(), it.first,
  188. std::make_unique<Value>(it.second->Clone()));
  189. }
  190. }
  191. Value::Value(LegacyDictStorage&& storage) noexcept
  192. : data_(absl::in_place_type_t<Dict>()) {
  193. dict() = std::move(storage);
  194. }
  195. Value::Value(absl::monostate) {}
  196. Value::Value(DoubleStorage storage) : data_(std::move(storage)) {}
  197. Value::DoubleStorage::DoubleStorage(double v) : v_(bit_cast<decltype(v_)>(v)) {
  198. if (!std::isfinite(v)) {
  199. NOTREACHED() << "Non-finite (i.e. NaN or positive/negative infinity) "
  200. << "values cannot be represented in JSON";
  201. v_ = bit_cast<decltype(v_)>(0.0);
  202. }
  203. }
  204. Value Value::Clone() const {
  205. return CloningHelper::Clone(data_);
  206. }
  207. Value::~Value() = default;
  208. // static
  209. const char* Value::GetTypeName(Value::Type type) {
  210. DCHECK_GE(static_cast<int>(type), 0);
  211. DCHECK_LT(static_cast<size_t>(type), std::size(kTypeNames));
  212. return kTypeNames[static_cast<size_t>(type)];
  213. }
  214. absl::optional<bool> Value::GetIfBool() const {
  215. return is_bool() ? absl::make_optional(GetBool()) : absl::nullopt;
  216. }
  217. absl::optional<int> Value::GetIfInt() const {
  218. return is_int() ? absl::make_optional(GetInt()) : absl::nullopt;
  219. }
  220. absl::optional<double> Value::GetIfDouble() const {
  221. return (is_int() || is_double()) ? absl::make_optional(GetDouble())
  222. : absl::nullopt;
  223. }
  224. const std::string* Value::GetIfString() const {
  225. return absl::get_if<std::string>(&data_);
  226. }
  227. std::string* Value::GetIfString() {
  228. return absl::get_if<std::string>(&data_);
  229. }
  230. const Value::BlobStorage* Value::GetIfBlob() const {
  231. return absl::get_if<BlobStorage>(&data_);
  232. }
  233. const Value::Dict* Value::GetIfDict() const {
  234. return absl::get_if<Dict>(&data_);
  235. }
  236. Value::Dict* Value::GetIfDict() {
  237. return absl::get_if<Dict>(&data_);
  238. }
  239. const Value::List* Value::GetIfList() const {
  240. return absl::get_if<List>(&data_);
  241. }
  242. Value::List* Value::GetIfList() {
  243. return absl::get_if<List>(&data_);
  244. }
  245. bool Value::GetBool() const {
  246. DCHECK(is_bool());
  247. return absl::get<bool>(data_);
  248. }
  249. int Value::GetInt() const {
  250. DCHECK(is_int());
  251. return absl::get<int>(data_);
  252. }
  253. double Value::GetDouble() const {
  254. if (is_double())
  255. return absl::get<DoubleStorage>(data_);
  256. if (is_int())
  257. return GetInt();
  258. CHECK(false);
  259. return 0.0;
  260. }
  261. const std::string& Value::GetString() const {
  262. DCHECK(is_string());
  263. return absl::get<std::string>(data_);
  264. }
  265. std::string& Value::GetString() {
  266. DCHECK(is_string());
  267. return absl::get<std::string>(data_);
  268. }
  269. const Value::BlobStorage& Value::GetBlob() const {
  270. DCHECK(is_blob());
  271. return absl::get<BlobStorage>(data_);
  272. }
  273. const Value::Dict& Value::GetDict() const {
  274. DCHECK(is_dict());
  275. return absl::get<Dict>(data_);
  276. }
  277. Value::Dict& Value::GetDict() {
  278. DCHECK(is_dict());
  279. return absl::get<Dict>(data_);
  280. }
  281. const Value::List& Value::GetList() const {
  282. DCHECK(is_list());
  283. return absl::get<List>(data_);
  284. }
  285. Value::List& Value::GetList() {
  286. DCHECK(is_list());
  287. return absl::get<List>(data_);
  288. }
  289. Value::Dict::Dict() = default;
  290. Value::Dict::Dict(Dict&&) noexcept = default;
  291. Value::Dict& Value::Dict::operator=(Dict&&) noexcept = default;
  292. Value::Dict::~Dict() = default;
  293. bool Value::Dict::empty() const {
  294. return storage_.empty();
  295. }
  296. size_t Value::Dict::size() const {
  297. return storage_.size();
  298. }
  299. Value::Dict::iterator Value::Dict::begin() {
  300. return iterator(storage_.begin());
  301. }
  302. Value::Dict::const_iterator Value::Dict::begin() const {
  303. return const_iterator(storage_.begin());
  304. }
  305. Value::Dict::const_iterator Value::Dict::cbegin() const {
  306. return const_iterator(storage_.cbegin());
  307. }
  308. Value::Dict::iterator Value::Dict::end() {
  309. return iterator(storage_.end());
  310. }
  311. Value::Dict::const_iterator Value::Dict::end() const {
  312. return const_iterator(storage_.end());
  313. }
  314. Value::Dict::const_iterator Value::Dict::cend() const {
  315. return const_iterator(storage_.cend());
  316. }
  317. bool Value::Dict::contains(base::StringPiece key) const {
  318. DCHECK(IsStringUTF8AllowingNoncharacters(key));
  319. return storage_.contains(key);
  320. }
  321. void Value::Dict::clear() {
  322. return storage_.clear();
  323. }
  324. Value::Dict::iterator Value::Dict::erase(iterator pos) {
  325. return iterator(storage_.erase(pos.GetUnderlyingIteratorDoNotUse()));
  326. }
  327. Value::Dict::iterator Value::Dict::erase(const_iterator pos) {
  328. return iterator(storage_.erase(pos.GetUnderlyingIteratorDoNotUse()));
  329. }
  330. Value::Dict Value::Dict::Clone() const {
  331. return Dict(storage_);
  332. }
  333. void Value::Dict::Merge(Dict dict) {
  334. for (const auto [key, value] : dict) {
  335. if (Dict* nested_dict = value.GetIfDict()) {
  336. if (Dict* current_dict = FindDict(key)) {
  337. // If `key` is a nested dictionary in this dictionary and the dictionary
  338. // being merged, recursively merge the two dictionaries.
  339. current_dict->Merge(std::move(*nested_dict));
  340. continue;
  341. }
  342. }
  343. // Otherwise, unconditionally set the value, overwriting any value that may
  344. // already be associated with the key.
  345. Set(key, std::move(value));
  346. }
  347. }
  348. const Value* Value::Dict::Find(StringPiece key) const {
  349. DCHECK(IsStringUTF8AllowingNoncharacters(key));
  350. auto it = storage_.find(key);
  351. return it != storage_.end() ? it->second.get() : nullptr;
  352. }
  353. Value* Value::Dict::Find(StringPiece key) {
  354. auto it = storage_.find(key);
  355. return it != storage_.end() ? it->second.get() : nullptr;
  356. }
  357. absl::optional<bool> Value::Dict::FindBool(StringPiece key) const {
  358. const Value* v = Find(key);
  359. return v ? v->GetIfBool() : absl::nullopt;
  360. }
  361. absl::optional<int> Value::Dict::FindInt(StringPiece key) const {
  362. const Value* v = Find(key);
  363. return v ? v->GetIfInt() : absl::nullopt;
  364. }
  365. absl::optional<double> Value::Dict::FindDouble(StringPiece key) const {
  366. const Value* v = Find(key);
  367. return v ? v->GetIfDouble() : absl::nullopt;
  368. }
  369. const std::string* Value::Dict::FindString(StringPiece key) const {
  370. const Value* v = Find(key);
  371. return v ? v->GetIfString() : nullptr;
  372. }
  373. std::string* Value::Dict::FindString(StringPiece key) {
  374. Value* v = Find(key);
  375. return v ? v->GetIfString() : nullptr;
  376. }
  377. const Value::BlobStorage* Value::Dict::FindBlob(StringPiece key) const {
  378. const Value* v = Find(key);
  379. return v ? v->GetIfBlob() : nullptr;
  380. }
  381. const Value::Dict* Value::Dict::FindDict(StringPiece key) const {
  382. const Value* v = Find(key);
  383. return v ? v->GetIfDict() : nullptr;
  384. }
  385. Value::Dict* Value::Dict::FindDict(StringPiece key) {
  386. Value* v = Find(key);
  387. return v ? v->GetIfDict() : nullptr;
  388. }
  389. const Value::List* Value::Dict::FindList(StringPiece key) const {
  390. const Value* v = Find(key);
  391. return v ? v->GetIfList() : nullptr;
  392. }
  393. Value::List* Value::Dict::FindList(StringPiece key) {
  394. Value* v = Find(key);
  395. return v ? v->GetIfList() : nullptr;
  396. }
  397. Value::Dict* Value::Dict::EnsureDict(StringPiece key) {
  398. Value::Dict* dict = FindDict(key);
  399. if (dict)
  400. return dict;
  401. return &Set(key, base::Value::Dict())->GetDict();
  402. }
  403. Value::List* Value::Dict::EnsureList(StringPiece key) {
  404. Value::List* list = FindList(key);
  405. if (list)
  406. return list;
  407. return &Set(key, base::Value::List())->GetList();
  408. }
  409. Value* Value::Dict::Set(StringPiece key, Value&& value) {
  410. DCHECK(IsStringUTF8AllowingNoncharacters(key));
  411. auto wrapped_value = std::make_unique<Value>(std::move(value));
  412. auto* raw_value = wrapped_value.get();
  413. storage_.insert_or_assign(key, std::move(wrapped_value));
  414. return raw_value;
  415. }
  416. Value* Value::Dict::Set(StringPiece key, bool value) {
  417. return Set(key, Value(value));
  418. }
  419. Value* Value::Dict::Set(StringPiece key, int value) {
  420. return Set(key, Value(value));
  421. }
  422. Value* Value::Dict::Set(StringPiece key, double value) {
  423. return Set(key, Value(value));
  424. }
  425. Value* Value::Dict::Set(StringPiece key, StringPiece value) {
  426. return Set(key, Value(value));
  427. }
  428. Value* Value::Dict::Set(StringPiece key, StringPiece16 value) {
  429. return Set(key, Value(value));
  430. }
  431. Value* Value::Dict::Set(StringPiece key, const char* value) {
  432. return Set(key, Value(value));
  433. }
  434. Value* Value::Dict::Set(StringPiece key, const char16_t* value) {
  435. return Set(key, Value(value));
  436. }
  437. Value* Value::Dict::Set(StringPiece key, std::string&& value) {
  438. return Set(key, Value(std::move(value)));
  439. }
  440. Value* Value::Dict::Set(StringPiece key, BlobStorage&& value) {
  441. return Set(key, Value(std::move(value)));
  442. }
  443. Value* Value::Dict::Set(StringPiece key, Dict&& value) {
  444. return Set(key, Value(std::move(value)));
  445. }
  446. Value* Value::Dict::Set(StringPiece key, List&& value) {
  447. return Set(key, Value(std::move(value)));
  448. }
  449. bool Value::Dict::Remove(StringPiece key) {
  450. DCHECK(IsStringUTF8AllowingNoncharacters(key));
  451. return storage_.erase(key) > 0;
  452. }
  453. absl::optional<Value> Value::Dict::Extract(StringPiece key) {
  454. DCHECK(IsStringUTF8AllowingNoncharacters(key));
  455. auto it = storage_.find(key);
  456. if (it == storage_.end())
  457. return absl::nullopt;
  458. Value v = std::move(*it->second);
  459. storage_.erase(it);
  460. return v;
  461. }
  462. const Value* Value::Dict::FindByDottedPath(StringPiece path) const {
  463. DCHECK(!path.empty());
  464. DCHECK(IsStringUTF8AllowingNoncharacters(path));
  465. const Dict* current_dict = this;
  466. const Value* current_value = nullptr;
  467. PathSplitter splitter(path);
  468. while (true) {
  469. current_value = current_dict->Find(splitter.Next());
  470. if (!splitter.HasNext()) {
  471. return current_value;
  472. }
  473. if (!current_value) {
  474. return nullptr;
  475. }
  476. current_dict = current_value->GetIfDict();
  477. if (!current_dict) {
  478. return nullptr;
  479. }
  480. }
  481. }
  482. Value* Value::Dict::FindByDottedPath(StringPiece path) {
  483. return const_cast<Value*>(as_const(*this).FindByDottedPath(path));
  484. }
  485. absl::optional<bool> Value::Dict::FindBoolByDottedPath(StringPiece path) const {
  486. const Value* v = FindByDottedPath(path);
  487. return v ? v->GetIfBool() : absl::nullopt;
  488. }
  489. absl::optional<int> Value::Dict::FindIntByDottedPath(StringPiece path) const {
  490. const Value* v = FindByDottedPath(path);
  491. return v ? v->GetIfInt() : absl::nullopt;
  492. }
  493. absl::optional<double> Value::Dict::FindDoubleByDottedPath(
  494. StringPiece path) const {
  495. const Value* v = FindByDottedPath(path);
  496. return v ? v->GetIfDouble() : absl::nullopt;
  497. }
  498. const std::string* Value::Dict::FindStringByDottedPath(StringPiece path) const {
  499. const Value* v = FindByDottedPath(path);
  500. return v ? v->GetIfString() : nullptr;
  501. }
  502. std::string* Value::Dict::FindStringByDottedPath(StringPiece path) {
  503. Value* v = FindByDottedPath(path);
  504. return v ? v->GetIfString() : nullptr;
  505. }
  506. const Value::BlobStorage* Value::Dict::FindBlobByDottedPath(
  507. StringPiece path) const {
  508. const Value* v = FindByDottedPath(path);
  509. return v ? v->GetIfBlob() : nullptr;
  510. }
  511. const Value::Dict* Value::Dict::FindDictByDottedPath(StringPiece path) const {
  512. const Value* v = FindByDottedPath(path);
  513. return v ? v->GetIfDict() : nullptr;
  514. }
  515. Value::Dict* Value::Dict::FindDictByDottedPath(StringPiece path) {
  516. Value* v = FindByDottedPath(path);
  517. return v ? v->GetIfDict() : nullptr;
  518. }
  519. const Value::List* Value::Dict::FindListByDottedPath(StringPiece path) const {
  520. const Value* v = FindByDottedPath(path);
  521. return v ? v->GetIfList() : nullptr;
  522. }
  523. Value::List* Value::Dict::FindListByDottedPath(StringPiece path) {
  524. Value* v = FindByDottedPath(path);
  525. return v ? v->GetIfList() : nullptr;
  526. }
  527. Value* Value::Dict::SetByDottedPath(StringPiece path, Value&& value) {
  528. DCHECK(!path.empty());
  529. DCHECK(IsStringUTF8AllowingNoncharacters(path));
  530. Dict* current_dict = this;
  531. Value* current_value = nullptr;
  532. PathSplitter splitter(path);
  533. while (true) {
  534. StringPiece next_key = splitter.Next();
  535. if (!splitter.HasNext()) {
  536. return current_dict->Set(next_key, std::move(value));
  537. }
  538. // This could be clever to avoid a double-lookup via use of lower_bound(),
  539. // but for now, just implement it the most straightforward way.
  540. current_value = current_dict->Find(next_key);
  541. if (current_value) {
  542. // Unlike the legacy DictionaryValue API, encountering an intermediate
  543. // node that is not a `Value::Type::DICT` is an error.
  544. current_dict = current_value->GetIfDict();
  545. if (!current_dict) {
  546. return nullptr;
  547. }
  548. } else {
  549. current_dict = &current_dict->Set(next_key, Dict())->GetDict();
  550. }
  551. }
  552. }
  553. Value* Value::Dict::SetByDottedPath(StringPiece path, bool value) {
  554. return SetByDottedPath(path, Value(value));
  555. }
  556. Value* Value::Dict::SetByDottedPath(StringPiece path, int value) {
  557. return SetByDottedPath(path, Value(value));
  558. }
  559. Value* Value::Dict::SetByDottedPath(StringPiece path, double value) {
  560. return SetByDottedPath(path, Value(value));
  561. }
  562. Value* Value::Dict::SetByDottedPath(StringPiece path, StringPiece value) {
  563. return SetByDottedPath(path, Value(value));
  564. }
  565. Value* Value::Dict::SetByDottedPath(StringPiece path, StringPiece16 value) {
  566. return SetByDottedPath(path, Value(value));
  567. }
  568. Value* Value::Dict::SetByDottedPath(StringPiece path, const char* value) {
  569. return SetByDottedPath(path, Value(value));
  570. }
  571. Value* Value::Dict::SetByDottedPath(StringPiece path, const char16_t* value) {
  572. return SetByDottedPath(path, Value(value));
  573. }
  574. Value* Value::Dict::SetByDottedPath(StringPiece path, std::string&& value) {
  575. return SetByDottedPath(path, Value(std::move(value)));
  576. }
  577. Value* Value::Dict::SetByDottedPath(StringPiece path, BlobStorage&& value) {
  578. return SetByDottedPath(path, Value(std::move(value)));
  579. }
  580. Value* Value::Dict::SetByDottedPath(StringPiece path, Dict&& value) {
  581. return SetByDottedPath(path, Value(std::move(value)));
  582. }
  583. Value* Value::Dict::SetByDottedPath(StringPiece path, List&& value) {
  584. return SetByDottedPath(path, Value(std::move(value)));
  585. }
  586. bool Value::Dict::RemoveByDottedPath(StringPiece path) {
  587. return ExtractByDottedPath(path).has_value();
  588. }
  589. absl::optional<Value> Value::Dict::ExtractByDottedPath(StringPiece path) {
  590. DCHECK(!path.empty());
  591. DCHECK(IsStringUTF8AllowingNoncharacters(path));
  592. // Use recursion instead of PathSplitter here, as it simplifies code for
  593. // removing dictionaries that become empty if a value matching `path` is
  594. // extracted.
  595. size_t dot_index = path.find('.');
  596. if (dot_index == StringPiece::npos) {
  597. return Extract(path);
  598. }
  599. // This could be clever to avoid a double-lookup by using storage_ directly,
  600. // but for now, just implement it in the most straightforward way.
  601. StringPiece next_key = path.substr(0, dot_index);
  602. auto* next_dict = FindDict(next_key);
  603. if (!next_dict) {
  604. return absl::nullopt;
  605. }
  606. absl::optional<Value> extracted =
  607. next_dict->ExtractByDottedPath(path.substr(dot_index + 1));
  608. if (extracted && next_dict->empty()) {
  609. Remove(next_key);
  610. }
  611. return extracted;
  612. }
  613. std::string Value::Dict::DebugString() const {
  614. return DebugStringImpl(*this);
  615. }
  616. #if BUILDFLAG(ENABLE_BASE_TRACING)
  617. void Value::Dict::WriteIntoTrace(perfetto::TracedValue context) const {
  618. perfetto::TracedDictionary dict = std::move(context).WriteDictionary();
  619. for (auto kv : *this) {
  620. dict.Add(perfetto::DynamicString(kv.first), kv.second);
  621. }
  622. }
  623. #endif // BUILDFLAG(ENABLE_BASE_TRACING)
  624. Value::Dict::Dict(
  625. const flat_map<std::string, std::unique_ptr<Value>>& storage) {
  626. storage_.reserve(storage.size());
  627. for (const auto& [key, value] : storage) {
  628. Set(key, value->Clone());
  629. }
  630. }
  631. bool operator==(const Value::Dict& lhs, const Value::Dict& rhs) {
  632. auto deref_2nd = [](const auto& p) { return std::tie(p.first, *p.second); };
  633. return ranges::equal(lhs.storage_, rhs.storage_, {}, deref_2nd, deref_2nd);
  634. }
  635. bool operator!=(const Value::Dict& lhs, const Value::Dict& rhs) {
  636. return !(lhs == rhs);
  637. }
  638. bool operator<(const Value::Dict& lhs, const Value::Dict& rhs) {
  639. auto deref_2nd = [](const auto& p) { return std::tie(p.first, *p.second); };
  640. return ranges::lexicographical_compare(lhs.storage_, rhs.storage_, {},
  641. deref_2nd, deref_2nd);
  642. }
  643. bool operator>(const Value::Dict& lhs, const Value::Dict& rhs) {
  644. return rhs < lhs;
  645. }
  646. bool operator<=(const Value::Dict& lhs, const Value::Dict& rhs) {
  647. return !(rhs < lhs);
  648. }
  649. bool operator>=(const Value::Dict& lhs, const Value::Dict& rhs) {
  650. return !(lhs < rhs);
  651. }
  652. Value::List::List() = default;
  653. Value::List::List(List&&) noexcept = default;
  654. Value::List& Value::List::operator=(List&&) noexcept = default;
  655. Value::List::~List() = default;
  656. bool Value::List::empty() const {
  657. return storage_.empty();
  658. }
  659. size_t Value::List::size() const {
  660. return storage_.size();
  661. }
  662. Value::List::iterator Value::List::begin() {
  663. return iterator(base::to_address(storage_.begin()),
  664. base::to_address(storage_.end()));
  665. }
  666. Value::List::const_iterator Value::List::begin() const {
  667. return const_iterator(base::to_address(storage_.begin()),
  668. base::to_address(storage_.end()));
  669. }
  670. Value::List::const_iterator Value::List::cbegin() const {
  671. return const_iterator(base::to_address(storage_.cbegin()),
  672. base::to_address(storage_.cend()));
  673. }
  674. Value::List::iterator Value::List::end() {
  675. return iterator(base::to_address(storage_.begin()),
  676. base::to_address(storage_.end()),
  677. base::to_address(storage_.end()));
  678. }
  679. Value::List::const_iterator Value::List::end() const {
  680. return const_iterator(base::to_address(storage_.begin()),
  681. base::to_address(storage_.end()),
  682. base::to_address(storage_.end()));
  683. }
  684. Value::List::const_iterator Value::List::cend() const {
  685. return const_iterator(base::to_address(storage_.cbegin()),
  686. base::to_address(storage_.cend()),
  687. base::to_address(storage_.cend()));
  688. }
  689. const Value& Value::List::front() const {
  690. CHECK(!storage_.empty());
  691. return storage_.front();
  692. }
  693. Value& Value::List::front() {
  694. CHECK(!storage_.empty());
  695. return storage_.front();
  696. }
  697. const Value& Value::List::back() const {
  698. CHECK(!storage_.empty());
  699. return storage_.back();
  700. }
  701. Value& Value::List::back() {
  702. CHECK(!storage_.empty());
  703. return storage_.back();
  704. }
  705. void Value::List::reserve(size_t capacity) {
  706. storage_.reserve(capacity);
  707. }
  708. const Value& Value::List::operator[](size_t index) const {
  709. CHECK_LT(index, storage_.size());
  710. return storage_[index];
  711. }
  712. Value& Value::List::operator[](size_t index) {
  713. CHECK_LT(index, storage_.size());
  714. return storage_[index];
  715. }
  716. void Value::List::clear() {
  717. storage_.clear();
  718. }
  719. Value::List::iterator Value::List::erase(iterator pos) {
  720. auto next_it = storage_.erase(storage_.begin() + (pos - begin()));
  721. return iterator(base::to_address(storage_.begin()), base::to_address(next_it),
  722. base::to_address(storage_.end()));
  723. }
  724. Value::List::const_iterator Value::List::erase(const_iterator pos) {
  725. auto next_it = storage_.erase(storage_.begin() + (pos - begin()));
  726. return const_iterator(base::to_address(storage_.begin()),
  727. base::to_address(next_it),
  728. base::to_address(storage_.end()));
  729. }
  730. Value::List::iterator Value::List::erase(iterator first, iterator last) {
  731. auto next_it = storage_.erase(storage_.begin() + (first - begin()),
  732. storage_.begin() + (last - begin()));
  733. return iterator(base::to_address(storage_.begin()), base::to_address(next_it),
  734. base::to_address(storage_.end()));
  735. }
  736. Value::List::const_iterator Value::List::erase(const_iterator first,
  737. const_iterator last) {
  738. auto next_it = storage_.erase(storage_.begin() + (first - begin()),
  739. storage_.begin() + (last - begin()));
  740. return const_iterator(base::to_address(storage_.begin()),
  741. base::to_address(next_it),
  742. base::to_address(storage_.end()));
  743. }
  744. Value::List Value::List::Clone() const {
  745. return List(storage_);
  746. }
  747. void Value::List::Append(Value&& value) {
  748. storage_.emplace_back(std::move(value));
  749. }
  750. void Value::List::Append(bool value) {
  751. storage_.emplace_back(value);
  752. }
  753. void Value::List::Append(int value) {
  754. storage_.emplace_back(value);
  755. }
  756. void Value::List::Append(double value) {
  757. storage_.emplace_back(value);
  758. }
  759. void Value::List::Append(StringPiece value) {
  760. Append(Value(value));
  761. }
  762. void Value::List::Append(StringPiece16 value) {
  763. storage_.emplace_back(value);
  764. }
  765. void Value::List::Append(const char* value) {
  766. storage_.emplace_back(value);
  767. }
  768. void Value::List::Append(const char16_t* value) {
  769. storage_.emplace_back(value);
  770. }
  771. void Value::List::Append(std::string&& value) {
  772. storage_.emplace_back(std::move(value));
  773. }
  774. void Value::List::Append(BlobStorage&& value) {
  775. storage_.emplace_back(std::move(value));
  776. }
  777. void Value::List::Append(Dict&& value) {
  778. storage_.emplace_back(std::move(value));
  779. }
  780. void Value::List::Append(List&& value) {
  781. storage_.emplace_back(std::move(value));
  782. }
  783. Value::List::iterator Value::List::Insert(const_iterator pos, Value&& value) {
  784. auto inserted_it =
  785. storage_.insert(storage_.begin() + (pos - begin()), std::move(value));
  786. return iterator(base::to_address(storage_.begin()),
  787. base::to_address(inserted_it),
  788. base::to_address(storage_.end()));
  789. }
  790. size_t Value::List::EraseValue(const Value& value) {
  791. return Erase(storage_, value);
  792. }
  793. std::string Value::List::DebugString() const {
  794. return DebugStringImpl(*this);
  795. }
  796. #if BUILDFLAG(ENABLE_BASE_TRACING)
  797. void Value::List::WriteIntoTrace(perfetto::TracedValue context) const {
  798. perfetto::TracedArray array = std::move(context).WriteArray();
  799. for (const auto& item : *this) {
  800. array.Append(item);
  801. }
  802. }
  803. #endif // BUILDFLAG(ENABLE_BASE_TRACING)
  804. Value::List::List(const std::vector<Value>& storage) {
  805. storage_.reserve(storage.size());
  806. for (const auto& value : storage) {
  807. storage_.push_back(value.Clone());
  808. }
  809. }
  810. bool operator==(const Value::List& lhs, const Value::List& rhs) {
  811. return lhs.storage_ == rhs.storage_;
  812. }
  813. bool operator!=(const Value::List& lhs, const Value::List& rhs) {
  814. return !(lhs == rhs);
  815. }
  816. bool operator<(const Value::List& lhs, const Value::List& rhs) {
  817. return lhs.storage_ < rhs.storage_;
  818. }
  819. bool operator>(const Value::List& lhs, const Value::List& rhs) {
  820. return rhs < lhs;
  821. }
  822. bool operator<=(const Value::List& lhs, const Value::List& rhs) {
  823. return !(rhs < lhs);
  824. }
  825. bool operator>=(const Value::List& lhs, const Value::List& rhs) {
  826. return !(lhs < rhs);
  827. }
  828. Value::ListView Value::GetListDeprecated() {
  829. return list();
  830. }
  831. Value::ConstListView Value::GetListDeprecated() const {
  832. return list();
  833. }
  834. void Value::Append(bool value) {
  835. GetList().Append(value);
  836. }
  837. void Value::Append(int value) {
  838. GetList().Append(value);
  839. }
  840. void Value::Append(double value) {
  841. GetList().Append(value);
  842. }
  843. void Value::Append(const char* value) {
  844. GetList().Append(value);
  845. }
  846. void Value::Append(StringPiece value) {
  847. GetList().Append(value);
  848. }
  849. void Value::Append(std::string&& value) {
  850. GetList().Append(std::move(value));
  851. }
  852. void Value::Append(StringPiece16 value) {
  853. GetList().Append(value);
  854. }
  855. void Value::Append(Value&& value) {
  856. GetList().Append(std::move(value));
  857. }
  858. bool Value::EraseListIter(CheckedContiguousConstIterator<Value> iter) {
  859. const auto offset = iter - ListView(list()).begin();
  860. auto list_iter = list().begin() + offset;
  861. if (list_iter == list().end())
  862. return false;
  863. list().erase(list_iter);
  864. return true;
  865. }
  866. size_t Value::EraseListValue(const Value& val) {
  867. return GetList().EraseValue(val);
  868. }
  869. void Value::ClearList() {
  870. GetList().clear();
  871. }
  872. Value* Value::FindKey(StringPiece key) {
  873. return GetDict().Find(key);
  874. }
  875. const Value* Value::FindKey(StringPiece key) const {
  876. return GetDict().Find(key);
  877. }
  878. Value* Value::FindKeyOfType(StringPiece key, Type type) {
  879. return const_cast<Value*>(as_const(*this).FindKeyOfType(key, type));
  880. }
  881. const Value* Value::FindKeyOfType(StringPiece key, Type type) const {
  882. const Value* result = FindKey(key);
  883. if (!result || result->type() != type)
  884. return nullptr;
  885. return result;
  886. }
  887. absl::optional<bool> Value::FindBoolKey(StringPiece key) const {
  888. return GetDict().FindBool(key);
  889. }
  890. absl::optional<int> Value::FindIntKey(StringPiece key) const {
  891. return GetDict().FindInt(key);
  892. }
  893. absl::optional<double> Value::FindDoubleKey(StringPiece key) const {
  894. return GetDict().FindDouble(key);
  895. }
  896. const std::string* Value::FindStringKey(StringPiece key) const {
  897. return GetDict().FindString(key);
  898. }
  899. std::string* Value::FindStringKey(StringPiece key) {
  900. return GetDict().FindString(key);
  901. }
  902. const Value::BlobStorage* Value::FindBlobKey(StringPiece key) const {
  903. return GetDict().FindBlob(key);
  904. }
  905. const Value* Value::FindDictKey(StringPiece key) const {
  906. return FindKeyOfType(key, Type::DICTIONARY);
  907. }
  908. Value* Value::FindDictKey(StringPiece key) {
  909. return FindKeyOfType(key, Type::DICTIONARY);
  910. }
  911. const Value* Value::FindListKey(StringPiece key) const {
  912. return FindKeyOfType(key, Type::LIST);
  913. }
  914. Value* Value::FindListKey(StringPiece key) {
  915. return FindKeyOfType(key, Type::LIST);
  916. }
  917. Value* Value::SetKey(StringPiece key, Value&& value) {
  918. return GetDict().Set(key, std::move(value));
  919. }
  920. Value* Value::SetBoolKey(StringPiece key, bool value) {
  921. return GetDict().Set(key, value);
  922. }
  923. Value* Value::SetIntKey(StringPiece key, int value) {
  924. return GetDict().Set(key, value);
  925. }
  926. Value* Value::SetDoubleKey(StringPiece key, double value) {
  927. return GetDict().Set(key, value);
  928. }
  929. Value* Value::SetStringKey(StringPiece key, StringPiece value) {
  930. return GetDict().Set(key, value);
  931. }
  932. Value* Value::SetStringKey(StringPiece key, StringPiece16 value) {
  933. return GetDict().Set(key, value);
  934. }
  935. Value* Value::SetStringKey(StringPiece key, const char* value) {
  936. return GetDict().Set(key, value);
  937. }
  938. Value* Value::SetStringKey(StringPiece key, std::string&& value) {
  939. return GetDict().Set(key, std::move(value));
  940. }
  941. bool Value::RemoveKey(StringPiece key) {
  942. return GetDict().Remove(key);
  943. }
  944. absl::optional<Value> Value::ExtractKey(StringPiece key) {
  945. return GetDict().Extract(key);
  946. }
  947. Value* Value::FindPath(StringPiece path) {
  948. return GetDict().FindByDottedPath(path);
  949. }
  950. const Value* Value::FindPath(StringPiece path) const {
  951. return GetDict().FindByDottedPath(path);
  952. }
  953. Value* Value::FindPathOfType(StringPiece path, Type type) {
  954. return const_cast<Value*>(as_const(*this).FindPathOfType(path, type));
  955. }
  956. const Value* Value::FindPathOfType(StringPiece path, Type type) const {
  957. const Value* cur = FindPath(path);
  958. if (!cur || cur->type() != type)
  959. return nullptr;
  960. return cur;
  961. }
  962. absl::optional<bool> Value::FindBoolPath(StringPiece path) const {
  963. return GetDict().FindBoolByDottedPath(path);
  964. }
  965. absl::optional<int> Value::FindIntPath(StringPiece path) const {
  966. return GetDict().FindIntByDottedPath(path);
  967. }
  968. absl::optional<double> Value::FindDoublePath(StringPiece path) const {
  969. return GetDict().FindDoubleByDottedPath(path);
  970. }
  971. const std::string* Value::FindStringPath(StringPiece path) const {
  972. return GetDict().FindStringByDottedPath(path);
  973. }
  974. std::string* Value::FindStringPath(StringPiece path) {
  975. return GetDict().FindStringByDottedPath(path);
  976. }
  977. const Value* Value::FindDictPath(StringPiece path) const {
  978. return FindPathOfType(path, Type::DICTIONARY);
  979. }
  980. Value* Value::FindDictPath(StringPiece path) {
  981. return FindPathOfType(path, Type::DICTIONARY);
  982. }
  983. const Value* Value::FindListPath(StringPiece path) const {
  984. return FindPathOfType(path, Type::LIST);
  985. }
  986. Value* Value::FindListPath(StringPiece path) {
  987. return FindPathOfType(path, Type::LIST);
  988. }
  989. Value* Value::SetPath(StringPiece path, Value&& value) {
  990. return GetDict().SetByDottedPath(path, std::move(value));
  991. }
  992. Value* Value::SetBoolPath(StringPiece path, bool value) {
  993. return GetDict().SetByDottedPath(path, value);
  994. }
  995. Value* Value::SetIntPath(StringPiece path, int value) {
  996. return GetDict().SetByDottedPath(path, value);
  997. }
  998. Value* Value::SetDoublePath(StringPiece path, double value) {
  999. return GetDict().SetByDottedPath(path, value);
  1000. }
  1001. Value* Value::SetStringPath(StringPiece path, StringPiece value) {
  1002. return GetDict().SetByDottedPath(path, value);
  1003. }
  1004. Value* Value::SetStringPath(StringPiece path, std::string&& value) {
  1005. return GetDict().SetByDottedPath(path, std::move(value));
  1006. }
  1007. Value* Value::SetStringPath(StringPiece path, const char* value) {
  1008. return GetDict().SetByDottedPath(path, value);
  1009. }
  1010. Value* Value::SetStringPath(StringPiece path, StringPiece16 value) {
  1011. return GetDict().SetByDottedPath(path, value);
  1012. }
  1013. bool Value::RemovePath(StringPiece path) {
  1014. return GetDict().RemoveByDottedPath(path);
  1015. }
  1016. absl::optional<Value> Value::ExtractPath(StringPiece path) {
  1017. return GetDict().ExtractByDottedPath(path);
  1018. }
  1019. // DEPRECATED METHODS
  1020. Value* Value::FindPath(std::initializer_list<StringPiece> path) {
  1021. return const_cast<Value*>(as_const(*this).FindPath(path));
  1022. }
  1023. Value* Value::FindPath(span<const StringPiece> path) {
  1024. return const_cast<Value*>(as_const(*this).FindPath(path));
  1025. }
  1026. const Value* Value::FindPath(std::initializer_list<StringPiece> path) const {
  1027. DCHECK_GE(path.size(), 2u) << "Use FindKey() for a path of length 1.";
  1028. return FindPath(make_span(path.begin(), path.size()));
  1029. }
  1030. const Value* Value::FindPath(span<const StringPiece> path) const {
  1031. const Value* cur = this;
  1032. for (const StringPiece& component : path) {
  1033. if (!cur->is_dict() || (cur = cur->FindKey(component)) == nullptr)
  1034. return nullptr;
  1035. }
  1036. return cur;
  1037. }
  1038. Value* Value::FindPathOfType(std::initializer_list<StringPiece> path,
  1039. Type type) {
  1040. return const_cast<Value*>(as_const(*this).FindPathOfType(path, type));
  1041. }
  1042. Value* Value::FindPathOfType(span<const StringPiece> path, Type type) {
  1043. return const_cast<Value*>(as_const(*this).FindPathOfType(path, type));
  1044. }
  1045. const Value* Value::FindPathOfType(std::initializer_list<StringPiece> path,
  1046. Type type) const {
  1047. DCHECK_GE(path.size(), 2u) << "Use FindKeyOfType() for a path of length 1.";
  1048. return FindPathOfType(make_span(path.begin(), path.size()), type);
  1049. }
  1050. const Value* Value::FindPathOfType(span<const StringPiece> path,
  1051. Type type) const {
  1052. const Value* result = FindPath(path);
  1053. if (!result || result->type() != type)
  1054. return nullptr;
  1055. return result;
  1056. }
  1057. Value* Value::SetPath(std::initializer_list<StringPiece> path, Value&& value) {
  1058. DCHECK_GE(path.size(), 2u) << "Use SetKey() for a path of length 1.";
  1059. return SetPath(make_span(path.begin(), path.size()), std::move(value));
  1060. }
  1061. Value* Value::SetPath(span<const StringPiece> path, Value&& value) {
  1062. DCHECK(path.begin() != path.end()); // Can't be empty path.
  1063. // Walk/construct intermediate dictionaries. The last element requires
  1064. // special handling so skip it in this loop.
  1065. Value* cur = this;
  1066. auto cur_path = path.begin();
  1067. for (; (cur_path + 1) < path.end(); ++cur_path) {
  1068. if (!cur->is_dict())
  1069. return nullptr;
  1070. // Use lower_bound to avoid doing the search twice for missing keys.
  1071. const StringPiece path_component = *cur_path;
  1072. auto found = cur->dict().lower_bound(path_component);
  1073. if (found == cur->dict().end() || found->first != path_component) {
  1074. // No key found, insert one.
  1075. auto inserted = cur->dict().try_emplace(
  1076. found, path_component, std::make_unique<Value>(Type::DICTIONARY));
  1077. cur = inserted->second.get();
  1078. } else {
  1079. cur = found->second.get();
  1080. }
  1081. }
  1082. // "cur" will now contain the last dictionary to insert or replace into.
  1083. if (!cur->is_dict())
  1084. return nullptr;
  1085. return cur->SetKey(*cur_path, std::move(value));
  1086. }
  1087. Value::dict_iterator_proxy Value::DictItems() {
  1088. return dict_iterator_proxy(&dict());
  1089. }
  1090. Value::const_dict_iterator_proxy Value::DictItems() const {
  1091. return const_dict_iterator_proxy(&dict());
  1092. }
  1093. size_t Value::DictSize() const {
  1094. return GetDict().size();
  1095. }
  1096. bool Value::DictEmpty() const {
  1097. return GetDict().empty();
  1098. }
  1099. void Value::DictClear() {
  1100. GetDict().clear();
  1101. }
  1102. void Value::MergeDictionary(const Value* dictionary) {
  1103. return GetDict().Merge(dictionary->GetDict().Clone());
  1104. }
  1105. bool Value::GetAsDictionary(DictionaryValue** out_value) {
  1106. if (out_value && is_dict()) {
  1107. *out_value = static_cast<DictionaryValue*>(this);
  1108. return true;
  1109. }
  1110. return is_dict();
  1111. }
  1112. bool Value::GetAsDictionary(const DictionaryValue** out_value) const {
  1113. if (out_value && is_dict()) {
  1114. *out_value = static_cast<const DictionaryValue*>(this);
  1115. return true;
  1116. }
  1117. return is_dict();
  1118. }
  1119. std::unique_ptr<Value> Value::CreateDeepCopy() const {
  1120. return std::make_unique<Value>(Clone());
  1121. }
  1122. bool operator==(const Value& lhs, const Value& rhs) {
  1123. return lhs.data_ == rhs.data_;
  1124. }
  1125. bool operator!=(const Value& lhs, const Value& rhs) {
  1126. return !(lhs == rhs);
  1127. }
  1128. bool operator<(const Value& lhs, const Value& rhs) {
  1129. return lhs.data_ < rhs.data_;
  1130. }
  1131. bool operator>(const Value& lhs, const Value& rhs) {
  1132. return rhs < lhs;
  1133. }
  1134. bool operator<=(const Value& lhs, const Value& rhs) {
  1135. return !(rhs < lhs);
  1136. }
  1137. bool operator>=(const Value& lhs, const Value& rhs) {
  1138. return !(lhs < rhs);
  1139. }
  1140. bool operator==(const Value& lhs, bool rhs) {
  1141. return lhs.is_bool() && lhs.GetBool() == rhs;
  1142. }
  1143. bool operator==(const Value& lhs, int rhs) {
  1144. return lhs.is_int() && lhs.GetInt() == rhs;
  1145. }
  1146. bool operator==(const Value& lhs, double rhs) {
  1147. return lhs.is_double() && lhs.GetDouble() == rhs;
  1148. }
  1149. bool operator==(const Value& lhs, StringPiece rhs) {
  1150. return lhs.is_string() && lhs.GetString() == rhs;
  1151. }
  1152. bool operator==(const Value& lhs, const Value::Dict& rhs) {
  1153. return lhs.is_dict() && lhs.GetDict() == rhs;
  1154. }
  1155. bool operator==(const Value& lhs, const Value::List& rhs) {
  1156. return lhs.is_list() && lhs.GetList() == rhs;
  1157. }
  1158. size_t Value::EstimateMemoryUsage() const {
  1159. switch (type()) {
  1160. #if BUILDFLAG(ENABLE_BASE_TRACING)
  1161. case Type::STRING:
  1162. return base::trace_event::EstimateMemoryUsage(GetString());
  1163. case Type::BINARY:
  1164. return base::trace_event::EstimateMemoryUsage(GetBlob());
  1165. case Type::DICTIONARY:
  1166. return base::trace_event::EstimateMemoryUsage(dict());
  1167. case Type::LIST:
  1168. return base::trace_event::EstimateMemoryUsage(list());
  1169. #endif // BUILDFLAG(ENABLE_BASE_TRACING)
  1170. default:
  1171. return 0;
  1172. }
  1173. }
  1174. std::string Value::DebugString() const {
  1175. return DebugStringImpl(*this);
  1176. }
  1177. #if BUILDFLAG(ENABLE_BASE_TRACING)
  1178. void Value::WriteIntoTrace(perfetto::TracedValue context) const {
  1179. Visit([&](const auto& member) {
  1180. using T = std::decay_t<decltype(member)>;
  1181. if constexpr (std::is_same_v<T, absl::monostate>) {
  1182. std::move(context).WriteString("<none>");
  1183. } else if constexpr (std::is_same_v<T, bool>) {
  1184. std::move(context).WriteBoolean(member);
  1185. } else if constexpr (std::is_same_v<T, int>) {
  1186. std::move(context).WriteInt64(member);
  1187. } else if constexpr (std::is_same_v<T, DoubleStorage>) {
  1188. std::move(context).WriteDouble(member);
  1189. } else if constexpr (std::is_same_v<T, std::string>) {
  1190. std::move(context).WriteString(member);
  1191. } else if constexpr (std::is_same_v<T, BlobStorage>) {
  1192. std::move(context).WriteString("<binary data not supported>");
  1193. } else if constexpr (std::is_same_v<T, Dict>) {
  1194. member.WriteIntoTrace(std::move(context));
  1195. } else if constexpr (std::is_same_v<T, List>) {
  1196. member.WriteIntoTrace(std::move(context));
  1197. }
  1198. });
  1199. }
  1200. #endif // BUILDFLAG(ENABLE_BASE_TRACING)
  1201. ///////////////////// DictionaryValue ////////////////////
  1202. // static
  1203. std::unique_ptr<DictionaryValue> DictionaryValue::From(
  1204. std::unique_ptr<Value> value) {
  1205. DictionaryValue* out;
  1206. if (value && value->GetAsDictionary(&out)) {
  1207. std::ignore = value.release();
  1208. return WrapUnique(out);
  1209. }
  1210. return nullptr;
  1211. }
  1212. DictionaryValue::DictionaryValue() : Value(Type::DICTIONARY) {}
  1213. DictionaryValue::DictionaryValue(const LegacyDictStorage& storage)
  1214. : Value(storage) {}
  1215. DictionaryValue::DictionaryValue(LegacyDictStorage&& storage) noexcept
  1216. : Value(std::move(storage)) {}
  1217. Value* DictionaryValue::Set(StringPiece path, std::unique_ptr<Value> in_value) {
  1218. DCHECK(IsStringUTF8AllowingNoncharacters(path));
  1219. DCHECK(in_value);
  1220. // IMPORTANT NOTE: Do not replace with GetDict.SetByDottedPath() yet, because
  1221. // the latter fails when over-writing a non-dict intermediate node, while this
  1222. // method just replaces it with one. This difference makes some tests actually
  1223. // fail (http://crbug.com/949461).
  1224. StringPiece current_path(path);
  1225. Value* current_dictionary = this;
  1226. for (size_t delimiter_position = current_path.find('.');
  1227. delimiter_position != StringPiece::npos;
  1228. delimiter_position = current_path.find('.')) {
  1229. // Assume that we're indexing into a dictionary.
  1230. StringPiece key = current_path.substr(0, delimiter_position);
  1231. Value* child_dictionary =
  1232. current_dictionary->FindKeyOfType(key, Type::DICTIONARY);
  1233. if (!child_dictionary) {
  1234. child_dictionary =
  1235. current_dictionary->SetKey(key, Value(Type::DICTIONARY));
  1236. }
  1237. current_dictionary = child_dictionary;
  1238. current_path = current_path.substr(delimiter_position + 1);
  1239. }
  1240. return static_cast<DictionaryValue*>(current_dictionary)
  1241. ->SetWithoutPathExpansion(current_path, std::move(in_value));
  1242. }
  1243. Value* DictionaryValue::SetBoolean(StringPiece path, bool in_value) {
  1244. return Set(path, std::make_unique<Value>(in_value));
  1245. }
  1246. Value* DictionaryValue::SetInteger(StringPiece path, int in_value) {
  1247. return Set(path, std::make_unique<Value>(in_value));
  1248. }
  1249. Value* DictionaryValue::SetString(StringPiece path, StringPiece in_value) {
  1250. return Set(path, std::make_unique<Value>(in_value));
  1251. }
  1252. Value* DictionaryValue::SetString(StringPiece path,
  1253. const std::u16string& in_value) {
  1254. return Set(path, std::make_unique<Value>(in_value));
  1255. }
  1256. ListValue* DictionaryValue::SetList(StringPiece path,
  1257. std::unique_ptr<ListValue> in_value) {
  1258. return static_cast<ListValue*>(Set(path, std::move(in_value)));
  1259. }
  1260. Value* DictionaryValue::SetWithoutPathExpansion(
  1261. StringPiece key,
  1262. std::unique_ptr<Value> in_value) {
  1263. // NOTE: We can't use |insert_or_assign| here, as only |try_emplace| does
  1264. // an explicit conversion from StringPiece to std::string if necessary.
  1265. auto result = dict().try_emplace(key, std::move(in_value));
  1266. if (!result.second) {
  1267. // in_value is guaranteed to be still intact at this point.
  1268. result.first->second = std::move(in_value);
  1269. }
  1270. return result.first->second.get();
  1271. }
  1272. bool DictionaryValue::Get(StringPiece path, const Value** out_value) const {
  1273. DCHECK(IsStringUTF8AllowingNoncharacters(path));
  1274. const Value* value = FindPath(path);
  1275. if (!value)
  1276. return false;
  1277. if (out_value)
  1278. *out_value = value;
  1279. return true;
  1280. }
  1281. bool DictionaryValue::Get(StringPiece path, Value** out_value) {
  1282. return as_const(*this).Get(path, const_cast<const Value**>(out_value));
  1283. }
  1284. bool DictionaryValue::GetInteger(StringPiece path, int* out_value) const {
  1285. const Value* value;
  1286. if (!Get(path, &value))
  1287. return false;
  1288. bool is_int = value->is_int();
  1289. if (is_int && out_value)
  1290. *out_value = value->GetInt();
  1291. return is_int;
  1292. }
  1293. bool DictionaryValue::GetString(StringPiece path,
  1294. std::string* out_value) const {
  1295. const Value* value;
  1296. if (!Get(path, &value))
  1297. return false;
  1298. const bool is_string = value->is_string();
  1299. if (is_string && out_value)
  1300. *out_value = value->GetString();
  1301. return is_string;
  1302. }
  1303. bool DictionaryValue::GetDictionary(StringPiece path,
  1304. const DictionaryValue** out_value) const {
  1305. const Value* value;
  1306. bool result = Get(path, &value);
  1307. if (!result || !value->is_dict())
  1308. return false;
  1309. if (out_value)
  1310. *out_value = static_cast<const DictionaryValue*>(value);
  1311. return true;
  1312. }
  1313. bool DictionaryValue::GetDictionary(StringPiece path,
  1314. DictionaryValue** out_value) {
  1315. return as_const(*this).GetDictionary(
  1316. path, const_cast<const DictionaryValue**>(out_value));
  1317. }
  1318. bool DictionaryValue::GetList(StringPiece path,
  1319. const ListValue** out_value) const {
  1320. const Value* value;
  1321. bool result = Get(path, &value);
  1322. if (!result || !value->is_list())
  1323. return false;
  1324. if (out_value)
  1325. *out_value = static_cast<const ListValue*>(value);
  1326. return true;
  1327. }
  1328. bool DictionaryValue::GetList(StringPiece path, ListValue** out_value) {
  1329. return as_const(*this).GetList(path,
  1330. const_cast<const ListValue**>(out_value));
  1331. }
  1332. void DictionaryValue::Swap(DictionaryValue* other) {
  1333. CHECK(other->is_dict());
  1334. dict().swap(other->dict());
  1335. }
  1336. DictionaryValue::Iterator::Iterator(const DictionaryValue& target)
  1337. : target_(target), it_(target.DictItems().begin()) {}
  1338. DictionaryValue::Iterator::Iterator(const Iterator& other) = default;
  1339. DictionaryValue::Iterator::~Iterator() = default;
  1340. std::unique_ptr<DictionaryValue> DictionaryValue::CreateDeepCopy() const {
  1341. return std::make_unique<DictionaryValue>(dict());
  1342. }
  1343. ///////////////////// ListValue ////////////////////
  1344. // static
  1345. std::unique_ptr<ListValue> ListValue::From(std::unique_ptr<Value> value) {
  1346. if (value && value->is_list())
  1347. return WrapUnique(static_cast<ListValue*>(value.release()));
  1348. return nullptr;
  1349. }
  1350. ListValue::ListValue() : Value(Type::LIST) {}
  1351. void ListValue::Append(base::Value::Dict in_dict) {
  1352. list().emplace_back(std::move(in_dict));
  1353. }
  1354. void ListValue::Append(base::Value::List in_list) {
  1355. list().emplace_back(std::move(in_list));
  1356. }
  1357. void ListValue::Swap(ListValue* other) {
  1358. CHECK(other->is_list());
  1359. list().swap(other->list());
  1360. }
  1361. ValueView::ValueView(const Value& value)
  1362. : data_view_(
  1363. value.Visit([](const auto& member) { return ViewType(member); })) {}
  1364. Value ValueView::ToValue() const {
  1365. return Value::CloningHelper::Clone(data_view_);
  1366. }
  1367. ValueSerializer::~ValueSerializer() = default;
  1368. ValueDeserializer::~ValueDeserializer() = default;
  1369. std::ostream& operator<<(std::ostream& out, const Value& value) {
  1370. return out << value.DebugString();
  1371. }
  1372. std::ostream& operator<<(std::ostream& out, const Value::Dict& dict) {
  1373. return out << dict.DebugString();
  1374. }
  1375. std::ostream& operator<<(std::ostream& out, const Value::List& list) {
  1376. return out << list.DebugString();
  1377. }
  1378. std::ostream& operator<<(std::ostream& out, const Value::Type& type) {
  1379. if (static_cast<int>(type) < 0 ||
  1380. static_cast<size_t>(type) >= std::size(kTypeNames))
  1381. return out << "Invalid Type (index = " << static_cast<int>(type) << ")";
  1382. return out << Value::GetTypeName(type);
  1383. }
  1384. } // namespace base