Chromium Code Reviews| Index: storage/browser/blob/blob_storage_registry.cc |
| diff --git a/storage/browser/blob/blob_storage_registry.cc b/storage/browser/blob/blob_storage_registry.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7bcfc7bf7ad4a11b70fd8c5d67d3cad40ba8129f |
| --- /dev/null |
| +++ b/storage/browser/blob/blob_storage_registry.cc |
| @@ -0,0 +1,132 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "storage/browser/blob/blob_storage_registry.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/callback.h" |
| +#include "base/location.h" |
| +#include "base/logging.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/stl_util.h" |
| +#include "url/gurl.h" |
| + |
| +namespace storage { |
| +using BlobState = BlobStorageRegistry::BlobState; |
| + |
| +namespace { |
| +// We can't use GURL directly for these hash fragment manipulations |
| +// since it doesn't have specific knowlege of the BlobURL format. GURL |
| +// treats BlobURLs as if they were PathURLs which don't support hash |
| +// fragments. |
| + |
| +bool BlobUrlHasRef(const GURL& url) { |
| + return url.spec().find('#') != std::string::npos; |
| +} |
| + |
| +GURL ClearBlobUrlRef(const GURL& url) { |
| + size_t hash_pos = url.spec().find('#'); |
| + if (hash_pos == std::string::npos) |
| + return url; |
| + return GURL(url.spec().substr(0, hash_pos)); |
| +} |
| + |
| +} // namespace |
| + |
| +BlobStorageRegistry::Entry::Entry(int refcount, BlobState state) |
| + : refcount(refcount), state(state), exceeded_memory(false) {} |
| + |
| +BlobStorageRegistry::Entry::~Entry() {} |
| + |
| +bool BlobStorageRegistry::Entry::TestAndSetState(BlobState expected, |
| + BlobState set) { |
| + if (state != expected) |
| + return false; |
| + state = set; |
| + return true; |
| +} |
| + |
| +BlobStorageRegistry::BlobStorageRegistry() {} |
| + |
| +BlobStorageRegistry::~BlobStorageRegistry() { |
| + // Note: We don't bother calling the construction complete callbacks, as we |
| + // are only being destructed at the end of the life of the browser process. |
| + // So it shouldn't matter. |
| + STLDeleteContainerPairSecondPointers(blob_map_.begin(), blob_map_.end()); |
| +} |
| + |
| +BlobStorageRegistry::Entry* BlobStorageRegistry::CreateEntry( |
| + const std::string& uuid) { |
| + DCHECK(!ContainsKey(blob_map_, uuid)); |
| + Entry* entry = new Entry(1, BlobState::RESERVED); |
| + blob_map_[uuid] = entry; |
| + return entry; |
| +} |
| + |
| +bool BlobStorageRegistry::DeleteEntry(const std::string& uuid) { |
| + BlobMap::iterator found = blob_map_.find(uuid); |
| + if (found == blob_map_.end()) { |
| + return false; |
| + } |
| + delete found->second; |
| + blob_map_.erase(found); |
| + return true; |
| +} |
| + |
| +bool BlobStorageRegistry::HasEntry(const std::string& uuid) const { |
| + return ContainsKey(blob_map_, uuid); |
| +} |
| + |
| +BlobStorageRegistry::Entry* BlobStorageRegistry::GetEntry( |
| + const std::string& uuid) const { |
| + BlobMap::const_iterator found = blob_map_.find(uuid); |
| + if (found == blob_map_.end()) { |
| + return nullptr; |
| + } |
| + return found->second; |
| +} |
| + |
| +bool BlobStorageRegistry::CreateUrlMapping(const GURL& blob_url, |
| + const std::string& uuid) { |
| + DCHECK(!BlobUrlHasRef(blob_url)); |
| + if (!HasEntry(uuid) || IsURLMapped(blob_url)) |
| + return false; |
| + url_to_uuid_[blob_url] = uuid; |
| + return true; |
| +} |
| + |
| +bool BlobStorageRegistry::DeleteURLMapping(const GURL& blob_url, |
| + std::string* uuid) { |
| + DCHECK(!BlobUrlHasRef(blob_url)); |
| + URLMap::iterator found = url_to_uuid_.find(blob_url); |
| + if (found == url_to_uuid_.end()) { |
| + return false; |
| + } |
|
kinuko
2015/10/12 14:34:58
nit: some one-line block has {} while some do not,
dmurph
2015/10/12 20:08:28
Fixed.
|
| + if (uuid) { |
| + uuid->assign(found->second); |
| + } |
| + url_to_uuid_.erase(found); |
| + return true; |
| +} |
| + |
| +bool BlobStorageRegistry::IsURLMapped(const GURL& blob_url) const { |
| + return ContainsKey(url_to_uuid_, blob_url); |
| +} |
| + |
| +BlobStorageRegistry::Entry* BlobStorageRegistry::GetEntryFromURL( |
| + const GURL& url, |
| + std::string* uuid) const { |
| + URLMap::const_iterator found = |
| + url_to_uuid_.find(BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url); |
| + if (found == url_to_uuid_.end()) { |
| + return nullptr; |
| + } |
| + Entry* entry = GetEntry(found->second); |
| + if (entry && uuid) { |
| + uuid->assign(found->second); |
| + } |
| + return entry; |
| +} |
| + |
| +} // namespace storage |