| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/renderer/renderer_webstoragearea_impl.h" | 5 #include "chrome/renderer/renderer_webstoragearea_impl.h" |
| 6 | 6 |
| 7 #include "chrome/common/render_messages.h" | 7 #include "chrome/common/render_messages.h" |
| 8 #include "chrome/renderer/render_thread.h" | 8 #include "chrome/renderer/render_thread.h" |
| 9 #include "webkit/api/public/WebString.h" | 9 #include "webkit/api/public/WebString.h" |
| 10 | 10 |
| 11 using WebKit::WebString; |
| 12 |
| 11 RendererWebStorageAreaImpl::RendererWebStorageAreaImpl( | 13 RendererWebStorageAreaImpl::RendererWebStorageAreaImpl( |
| 12 int64 namespace_id, | 14 int64 namespace_id, |
| 13 const WebKit::WebString& origin) | 15 const WebString& origin) |
| 14 : namespace_id_(namespace_id), | 16 : namespace_id_(namespace_id), |
| 15 origin_(origin), | 17 origin_(origin), |
| 16 storage_area_id_(kUninitializedStorageAreaId), | 18 storage_area_id_(kUninitializedStorageAreaId), |
| 17 lock_held_(false), | 19 lock_held_(false), |
| 18 bytes_left_in_quota_(0) { | 20 bytes_left_in_quota_(0) { |
| 19 } | 21 } |
| 20 | 22 |
| 21 RendererWebStorageAreaImpl::~RendererWebStorageAreaImpl() { | 23 RendererWebStorageAreaImpl::~RendererWebStorageAreaImpl() { |
| 22 } | 24 } |
| 23 | 25 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 38 EnsureInitializedAndLocked(); | 40 EnsureInitializedAndLocked(); |
| 39 // Right now this is always sync. We could cache it, but I can't think of | 41 // Right now this is always sync. We could cache it, but I can't think of |
| 40 // too many use cases where you'd repeatedly look up length() and not be | 42 // too many use cases where you'd repeatedly look up length() and not be |
| 41 // doing so many key() lookups that the length() calls are the problem. | 43 // doing so many key() lookups that the length() calls are the problem. |
| 42 unsigned length; | 44 unsigned length; |
| 43 RenderThread::current()->Send( | 45 RenderThread::current()->Send( |
| 44 new ViewHostMsg_DOMStorageLength(storage_area_id_, &length)); | 46 new ViewHostMsg_DOMStorageLength(storage_area_id_, &length)); |
| 45 return length; | 47 return length; |
| 46 } | 48 } |
| 47 | 49 |
| 48 WebKit::WebString RendererWebStorageAreaImpl::key(unsigned index) { | 50 WebString RendererWebStorageAreaImpl::key(unsigned index) { |
| 49 EnsureInitializedAndLocked(); | 51 EnsureInitializedAndLocked(); |
| 50 // Right now this is always sync. We may want to optimize this by fetching | 52 // Right now this is always sync. We may want to optimize this by fetching |
| 51 // chunks of keys rather than single keys (and flushing the cache on every | 53 // chunks of keys rather than single keys (and flushing the cache on every |
| 52 // mutation of the storage area) since this will most often be used to fetch | 54 // mutation of the storage area) since this will most often be used to fetch |
| 53 // all the keys at once. | 55 // all the keys at once. |
| 54 string16 key; | 56 NullableString16 key; |
| 55 bool key_is_null; | |
| 56 RenderThread::current()->Send( | 57 RenderThread::current()->Send( |
| 57 new ViewHostMsg_DOMStorageKey(storage_area_id_, index, | 58 new ViewHostMsg_DOMStorageKey(storage_area_id_, index, &key)); |
| 58 &key, &key_is_null)); | 59 return key; |
| 59 return key_is_null ? WebKit::WebString() : WebKit::WebString(key); | |
| 60 } | 60 } |
| 61 | 61 |
| 62 WebKit::WebString RendererWebStorageAreaImpl::getItem( | 62 WebString RendererWebStorageAreaImpl::getItem(const WebString& webkit_key) { |
| 63 const WebKit::WebString& webkit_key) { | |
| 64 EnsureInitializedAndLocked(); | 63 EnsureInitializedAndLocked(); |
| 65 string16 key = webkit_key; | 64 string16 key = webkit_key; |
| 66 | 65 |
| 67 // Return from our cache if possible. | 66 // Return from our cache if possible. |
| 68 CacheMap::const_iterator iterator = cached_items_.find(key); | 67 CacheMap::const_iterator iterator = cached_items_.find(key); |
| 69 if (iterator != cached_items_.end()) | 68 if (iterator != cached_items_.end()) |
| 70 return iterator->second; | 69 return iterator->second; |
| 71 if (cached_invalid_items_.find(key) != cached_invalid_items_.end()) | 70 if (cached_invalid_items_.find(key) != cached_invalid_items_.end()) |
| 72 return WebKit::WebString(); // Return a "null" string. | 71 return WebString(); // Return a "null" string. |
| 73 | 72 |
| 74 // The item is not in the cache, so we must do a sync IPC. Afterwards, | 73 // The item is not in the cache, so we must do a sync IPC. Afterwards, |
| 75 // add it to the cache. | 74 // add it to the cache. |
| 76 string16 raw_value; | 75 NullableString16 raw_value; |
| 77 bool value_is_null; | |
| 78 RenderThread::current()->Send( | 76 RenderThread::current()->Send( |
| 79 new ViewHostMsg_DOMStorageGetItem(storage_area_id_, key, | 77 new ViewHostMsg_DOMStorageGetItem(storage_area_id_, key, &raw_value)); |
| 80 &raw_value, &value_is_null)); | 78 WebString value = raw_value; // Only do the conversion once. |
| 81 WebKit::WebString value = value_is_null ? WebKit::WebString() | |
| 82 : WebKit::WebString(raw_value); | |
| 83 SetCache(key, value); | 79 SetCache(key, value); |
| 84 return value; | 80 return value; |
| 85 } | 81 } |
| 86 | 82 |
| 87 void RendererWebStorageAreaImpl::setItem(const WebKit::WebString& key, | 83 void RendererWebStorageAreaImpl::setItem(const WebString& key, |
| 88 const WebKit::WebString& value, | 84 const WebString& value, |
| 89 bool& quota_exception) { | 85 bool& quota_exception) { |
| 90 EnsureInitializedAndLocked(); | 86 EnsureInitializedAndLocked(); |
| 91 quota_exception = !UpdateQuota(key, value); | 87 quota_exception = !UpdateQuota(key, value); |
| 92 if (quota_exception) | 88 if (quota_exception) |
| 93 return; | 89 return; |
| 94 RenderThread::current()->Send( | 90 RenderThread::current()->Send( |
| 95 new ViewHostMsg_DOMStorageSetItem(storage_area_id_, key, value)); | 91 new ViewHostMsg_DOMStorageSetItem(storage_area_id_, key, value)); |
| 96 SetCache(key, value); | 92 SetCache(key, value); |
| 97 } | 93 } |
| 98 | 94 |
| 99 void RendererWebStorageAreaImpl::removeItem(const WebKit::WebString& key) { | 95 void RendererWebStorageAreaImpl::removeItem(const WebString& key) { |
| 100 EnsureInitializedAndLocked(); | 96 EnsureInitializedAndLocked(); |
| 101 bool update_succeeded = UpdateQuota(key, WebKit::WebString()); | 97 bool update_succeeded = UpdateQuota(key, WebString()); |
| 102 DCHECK(update_succeeded); | 98 DCHECK(update_succeeded); |
| 103 RenderThread::current()->Send( | 99 RenderThread::current()->Send( |
| 104 new ViewHostMsg_DOMStorageRemoveItem(storage_area_id_, key)); | 100 new ViewHostMsg_DOMStorageRemoveItem(storage_area_id_, key)); |
| 105 SetCache(key, WebKit::WebString()); | 101 SetCache(key, WebString()); |
| 106 } | 102 } |
| 107 | 103 |
| 108 void RendererWebStorageAreaImpl::clear() { | 104 void RendererWebStorageAreaImpl::clear() { |
| 109 EnsureInitializedAndLocked(); | 105 EnsureInitializedAndLocked(); |
| 110 RenderThread::current()->Send( | 106 RenderThread::current()->Send( |
| 111 new ViewHostMsg_DOMStorageClear(storage_area_id_, | 107 new ViewHostMsg_DOMStorageClear(storage_area_id_, |
| 112 &bytes_left_in_quota_)); | 108 &bytes_left_in_quota_)); |
| 113 // A possible optimization is a flag that says our cache is 100% complete. | 109 // A possible optimization is a flag that says our cache is 100% complete. |
| 114 // This could be set here, and then future gets would never require IPC. | 110 // This could be set here, and then future gets would never require IPC. |
| 115 cached_items_.clear(); | 111 cached_items_.clear(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 130 RenderThread::current()->Send( | 126 RenderThread::current()->Send( |
| 131 new ViewHostMsg_DOMStorageLock(storage_area_id_, &invalidate_cache, | 127 new ViewHostMsg_DOMStorageLock(storage_area_id_, &invalidate_cache, |
| 132 &bytes_left_in_quota_)); | 128 &bytes_left_in_quota_)); |
| 133 lock_held_ = true; | 129 lock_held_ = true; |
| 134 if (invalidate_cache) { | 130 if (invalidate_cache) { |
| 135 cached_items_.clear(); | 131 cached_items_.clear(); |
| 136 cached_invalid_items_.clear(); | 132 cached_invalid_items_.clear(); |
| 137 } | 133 } |
| 138 } | 134 } |
| 139 | 135 |
| 140 bool RendererWebStorageAreaImpl::UpdateQuota(const WebKit::WebString& key, | 136 bool RendererWebStorageAreaImpl::UpdateQuota(const WebString& key, |
| 141 const WebKit::WebString& value) { | 137 const WebString& value) { |
| 142 // TODO(jorlow): Remove once the bytes_left_in_quota values we're getting | 138 // TODO(jorlow): Remove once the bytes_left_in_quota values we're getting |
| 143 // are accurate. | 139 // are accurate. |
| 144 return true; | 140 return true; |
| 145 | 141 |
| 146 size_t existing_bytes = getItem(key).length(); | 142 size_t existing_bytes = getItem(key).length(); |
| 147 size_t new_bytes = value.length(); | 143 size_t new_bytes = value.length(); |
| 148 | 144 |
| 149 if (existing_bytes < new_bytes) { | 145 if (existing_bytes < new_bytes) { |
| 150 size_t delta = new_bytes - existing_bytes; | 146 size_t delta = new_bytes - existing_bytes; |
| 151 if (delta > bytes_left_in_quota_) | 147 if (delta > bytes_left_in_quota_) |
| 152 return false; | 148 return false; |
| 153 bytes_left_in_quota_ -= delta; | 149 bytes_left_in_quota_ -= delta; |
| 154 } else { | 150 } else { |
| 155 size_t delta = existing_bytes - new_bytes; | 151 size_t delta = existing_bytes - new_bytes; |
| 156 DCHECK(delta + bytes_left_in_quota_ >= bytes_left_in_quota_); | 152 DCHECK(delta + bytes_left_in_quota_ >= bytes_left_in_quota_); |
| 157 bytes_left_in_quota_ += delta; | 153 bytes_left_in_quota_ += delta; |
| 158 } | 154 } |
| 159 return true; | 155 return true; |
| 160 } | 156 } |
| 161 | 157 |
| 162 void RendererWebStorageAreaImpl::SetCache(const string16& key, | 158 void RendererWebStorageAreaImpl::SetCache(const string16& key, |
| 163 const WebKit::WebString& value) { | 159 const WebString& value) { |
| 164 cached_items_.erase(key); | 160 cached_items_.erase(key); |
| 165 cached_invalid_items_.erase(key); | 161 cached_invalid_items_.erase(key); |
| 166 | 162 |
| 167 if (!value.isNull()) | 163 if (!value.isNull()) |
| 168 cached_items_[key] = value; | 164 cached_items_[key] = value; |
| 169 else | 165 else |
| 170 cached_invalid_items_.insert(key); | 166 cached_invalid_items_.insert(key); |
| 171 } | 167 } |
| OLD | NEW |