• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }