1 // Copyright 2017 The Chromium Embedded Framework Authors.
2 // Portions copyright 2016 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include "libcef/browser/extensions/value_store/cef_value_store.h"
7
8 #include <memory>
9 #include <ostream>
10 #include <utility>
11
12 #include "base/notreached.h"
13
14 namespace value_store {
15
16 namespace {
17
18 const char kGenericErrorMessage[] = "CefValueStore configured to error";
19
20 // Having this utility function allows ValueStore::Status to not have a copy
21 // constructor.
CreateStatusCopy(const ValueStore::Status & status)22 ValueStore::Status CreateStatusCopy(const ValueStore::Status& status) {
23 return ValueStore::Status(status.code, status.restore_status, status.message);
24 }
25
26 } // namespace
27
28 CefValueStore::CefValueStore() = default;
29 CefValueStore::~CefValueStore() = default;
30
set_status_code(StatusCode status_code)31 void CefValueStore::set_status_code(StatusCode status_code) {
32 status_ = ValueStore::Status(status_code, kGenericErrorMessage);
33 }
34
GetBytesInUse(const std::string & key)35 size_t CefValueStore::GetBytesInUse(const std::string& key) {
36 // Let SettingsStorageQuotaEnforcer implement this.
37 NOTREACHED() << "Not implemented";
38 return 0;
39 }
40
GetBytesInUse(const std::vector<std::string> & keys)41 size_t CefValueStore::GetBytesInUse(const std::vector<std::string>& keys) {
42 // Let SettingsStorageQuotaEnforcer implement this.
43 NOTREACHED() << "Not implemented";
44 return 0;
45 }
46
GetBytesInUse()47 size_t CefValueStore::GetBytesInUse() {
48 // Let SettingsStorageQuotaEnforcer implement this.
49 NOTREACHED() << "Not implemented";
50 return 0;
51 }
52
Get(const std::string & key)53 ValueStore::ReadResult CefValueStore::Get(const std::string& key) {
54 return Get(std::vector<std::string>(1, key));
55 }
56
Get(const std::vector<std::string> & keys)57 ValueStore::ReadResult CefValueStore::Get(
58 const std::vector<std::string>& keys) {
59 read_count_++;
60 if (!status_.ok())
61 return ReadResult(CreateStatusCopy(status_));
62
63 auto settings = std::make_unique<base::DictionaryValue>();
64 for (const auto& key : keys) {
65 base::Value* value = storage_.FindKey(key);
66 if (value) {
67 settings->SetKey(key, value->Clone());
68 }
69 }
70 return ReadResult(std::move(settings), CreateStatusCopy(status_));
71 }
72
Get()73 ValueStore::ReadResult CefValueStore::Get() {
74 read_count_++;
75 if (!status_.ok())
76 return ReadResult(CreateStatusCopy(status_));
77 return ReadResult(storage_.CreateDeepCopy(), CreateStatusCopy(status_));
78 }
79
Set(WriteOptions options,const std::string & key,const base::Value & value)80 ValueStore::WriteResult CefValueStore::Set(WriteOptions options,
81 const std::string& key,
82 const base::Value& value) {
83 base::DictionaryValue settings;
84 settings.SetKey(key, value.Clone());
85 return Set(options, settings);
86 }
87
Set(WriteOptions options,const base::DictionaryValue & settings)88 ValueStore::WriteResult CefValueStore::Set(
89 WriteOptions options,
90 const base::DictionaryValue& settings) {
91 write_count_++;
92 if (!status_.ok())
93 return WriteResult(CreateStatusCopy(status_));
94
95 ValueStoreChangeList changes;
96 for (base::DictionaryValue::Iterator it(settings); !it.IsAtEnd();
97 it.Advance()) {
98 base::Value* old_value = storage_.FindKey(it.key());
99 if (!old_value || *old_value != it.value()) {
100 changes.emplace_back(it.key(),
101 old_value
102 ? absl::optional<base::Value>(old_value->Clone())
103 : absl::nullopt,
104 it.value().Clone());
105 storage_.SetKey(it.key(), it.value().Clone());
106 }
107 }
108 return WriteResult(std::move(changes), CreateStatusCopy(status_));
109 }
110
Remove(const std::string & key)111 ValueStore::WriteResult CefValueStore::Remove(const std::string& key) {
112 return Remove(std::vector<std::string>(1, key));
113 }
114
Remove(const std::vector<std::string> & keys)115 ValueStore::WriteResult CefValueStore::Remove(
116 const std::vector<std::string>& keys) {
117 write_count_++;
118 if (!status_.ok())
119 return WriteResult(CreateStatusCopy(status_));
120
121 ValueStoreChangeList changes;
122 for (auto const& key : keys) {
123 absl::optional<base::Value> old_value = storage_.ExtractKey(key);
124 if (old_value.has_value()) {
125 changes.emplace_back(key, std::move(*old_value), absl::nullopt);
126 }
127 }
128 return WriteResult(std::move(changes), CreateStatusCopy(status_));
129 }
130
Clear()131 ValueStore::WriteResult CefValueStore::Clear() {
132 std::vector<std::string> keys;
133 for (base::DictionaryValue::Iterator it(storage_); !it.IsAtEnd();
134 it.Advance()) {
135 keys.push_back(it.key());
136 }
137 return Remove(keys);
138 }
139
140 } // namespace value_store
141