• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 
5 #include "content/common/dom_storage/dom_storage_map.h"
6 
7 #include "base/logging.h"
8 
9 namespace content {
10 
11 namespace {
12 
size_of_item(const base::string16 & key,const base::string16 & value)13 size_t size_of_item(const base::string16& key, const base::string16& value) {
14   return (key.length() + value.length()) * sizeof(base::char16);
15 }
16 
CountBytes(const DOMStorageValuesMap & values)17 size_t CountBytes(const DOMStorageValuesMap& values) {
18   if (values.size() == 0)
19     return 0;
20 
21   size_t count = 0;
22   DOMStorageValuesMap::const_iterator it = values.begin();
23   for (; it != values.end(); ++it)
24     count += size_of_item(it->first, it->second.string());
25   return count;
26 }
27 
28 }  // namespace
29 
DOMStorageMap(size_t quota)30 DOMStorageMap::DOMStorageMap(size_t quota)
31     : bytes_used_(0),
32       quota_(quota) {
33   ResetKeyIterator();
34 }
35 
~DOMStorageMap()36 DOMStorageMap::~DOMStorageMap() {}
37 
Length() const38 unsigned DOMStorageMap::Length() const {
39   return values_.size();
40 }
41 
Key(unsigned index)42 base::NullableString16 DOMStorageMap::Key(unsigned index) {
43   if (index >= values_.size())
44     return base::NullableString16();
45   while (last_key_index_ != index) {
46     if (last_key_index_ > index) {
47       --key_iterator_;
48       --last_key_index_;
49     } else {
50       ++key_iterator_;
51       ++last_key_index_;
52     }
53   }
54   return base::NullableString16(key_iterator_->first, false);
55 }
56 
GetItem(const base::string16 & key) const57 base::NullableString16 DOMStorageMap::GetItem(const base::string16& key) const {
58   DOMStorageValuesMap::const_iterator found = values_.find(key);
59   if (found == values_.end())
60     return base::NullableString16();
61   return found->second;
62 }
63 
SetItem(const base::string16 & key,const base::string16 & value,base::NullableString16 * old_value)64 bool DOMStorageMap::SetItem(
65     const base::string16& key, const base::string16& value,
66     base::NullableString16* old_value) {
67   DOMStorageValuesMap::const_iterator found = values_.find(key);
68   if (found == values_.end())
69     *old_value = base::NullableString16();
70   else
71     *old_value = found->second;
72 
73   size_t old_item_size = old_value->is_null() ?
74       0 : size_of_item(key, old_value->string());
75   size_t new_item_size = size_of_item(key, value);
76   size_t new_bytes_used = bytes_used_ - old_item_size + new_item_size;
77 
78   // Only check quota if the size is increasing, this allows
79   // shrinking changes to pre-existing files that are over budget.
80   if (new_item_size > old_item_size && new_bytes_used > quota_)
81     return false;
82 
83   values_[key] = base::NullableString16(value, false);
84   ResetKeyIterator();
85   bytes_used_ = new_bytes_used;
86   return true;
87 }
88 
RemoveItem(const base::string16 & key,base::string16 * old_value)89 bool DOMStorageMap::RemoveItem(
90     const base::string16& key,
91     base::string16* old_value) {
92   DOMStorageValuesMap::iterator found = values_.find(key);
93   if (found == values_.end())
94     return false;
95   *old_value = found->second.string();
96   values_.erase(found);
97   ResetKeyIterator();
98   bytes_used_ -= size_of_item(key, *old_value);
99   return true;
100 }
101 
SwapValues(DOMStorageValuesMap * values)102 void DOMStorageMap::SwapValues(DOMStorageValuesMap* values) {
103   // Note: A pre-existing file may be over the quota budget.
104   values_.swap(*values);
105   bytes_used_ = CountBytes(values_);
106   ResetKeyIterator();
107 }
108 
DeepCopy() const109 DOMStorageMap* DOMStorageMap::DeepCopy() const {
110   DOMStorageMap* copy = new DOMStorageMap(quota_);
111   copy->values_ = values_;
112   copy->bytes_used_ = bytes_used_;
113   copy->ResetKeyIterator();
114   return copy;
115 }
116 
ResetKeyIterator()117 void DOMStorageMap::ResetKeyIterator() {
118   key_iterator_ = values_.begin();
119   last_key_index_ = 0;
120 }
121 
122 }  // namespace content
123