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 <utility>
9
10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/notreached.h"
13
14 namespace {
15
16 const char kGenericErrorMessage[] = "CefValueStore configured to error";
17
18 // Having this utility function allows ValueStore::Status to not have a copy
19 // constructor.
CreateStatusCopy(const ValueStore::Status & status)20 ValueStore::Status CreateStatusCopy(const ValueStore::Status& status) {
21 return ValueStore::Status(status.code, status.restore_status, status.message);
22 }
23
24 } // namespace
25
CefValueStore()26 CefValueStore::CefValueStore() : read_count_(0), write_count_(0) {}
27
~CefValueStore()28 CefValueStore::~CefValueStore() {}
29
set_status_code(StatusCode status_code)30 void CefValueStore::set_status_code(StatusCode status_code) {
31 status_ = ValueStore::Status(status_code, kGenericErrorMessage);
32 }
33
GetBytesInUse(const std::string & key)34 size_t CefValueStore::GetBytesInUse(const std::string& key) {
35 // Let SettingsStorageQuotaEnforcer implement this.
36 NOTREACHED();
37 return 0;
38 }
39
GetBytesInUse(const std::vector<std::string> & keys)40 size_t CefValueStore::GetBytesInUse(const std::vector<std::string>& keys) {
41 // Let SettingsStorageQuotaEnforcer implement this.
42 NOTREACHED();
43 return 0;
44 }
45
GetBytesInUse()46 size_t CefValueStore::GetBytesInUse() {
47 // Let SettingsStorageQuotaEnforcer implement this.
48 NOTREACHED();
49 return 0;
50 }
51
Get(const std::string & key)52 ValueStore::ReadResult CefValueStore::Get(const std::string& key) {
53 return Get(std::vector<std::string>(1, key));
54 }
55
Get(const std::vector<std::string> & keys)56 ValueStore::ReadResult CefValueStore::Get(
57 const std::vector<std::string>& keys) {
58 read_count_++;
59 if (!status_.ok())
60 return ReadResult(CreateStatusCopy(status_));
61
62 auto settings = std::make_unique<base::DictionaryValue>();
63 for (std::vector<std::string>::const_iterator it = keys.begin();
64 it != keys.end(); ++it) {
65 base::Value* value = nullptr;
66 if (storage_.GetWithoutPathExpansion(*it, &value)) {
67 settings->SetWithoutPathExpansion(*it, value->CreateDeepCopy());
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.SetWithoutPathExpansion(key, value.CreateDeepCopy());
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 = NULL;
99 if (!storage_.GetWithoutPathExpansion(it.key(), &old_value) ||
100 !old_value->Equals(&it.value())) {
101 changes.emplace_back(it.key(),
102 old_value
103 ? base::Optional<base::Value>(old_value->Clone())
104 : base::nullopt,
105 it.value().Clone());
106 storage_.SetWithoutPathExpansion(it.key(), it.value().CreateDeepCopy());
107 }
108 }
109 return WriteResult(std::move(changes), CreateStatusCopy(status_));
110 }
111
Remove(const std::string & key)112 ValueStore::WriteResult CefValueStore::Remove(const std::string& key) {
113 return Remove(std::vector<std::string>(1, key));
114 }
115
Remove(const std::vector<std::string> & keys)116 ValueStore::WriteResult CefValueStore::Remove(
117 const std::vector<std::string>& keys) {
118 write_count_++;
119 if (!status_.ok())
120 return WriteResult(CreateStatusCopy(status_));
121
122 ValueStoreChangeList changes;
123 for (auto it = keys.cbegin(); it != keys.cend(); ++it) {
124 std::unique_ptr<base::Value> old_value;
125 if (storage_.RemoveWithoutPathExpansion(*it, &old_value)) {
126 changes.emplace_back(*it, std::move(*old_value), base::nullopt);
127 }
128 }
129 return WriteResult(std::move(changes), CreateStatusCopy(status_));
130 }
131
Clear()132 ValueStore::WriteResult CefValueStore::Clear() {
133 std::vector<std::string> keys;
134 for (base::DictionaryValue::Iterator it(storage_); !it.IsAtEnd();
135 it.Advance()) {
136 keys.push_back(it.key());
137 }
138 return Remove(keys);
139 }