diff options
Diffstat (limited to 'storage/browser/blob/blob_storage_registry.cc')
-rw-r--r-- | storage/browser/blob/blob_storage_registry.cc | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/storage/browser/blob/blob_storage_registry.cc b/storage/browser/blob/blob_storage_registry.cc new file mode 100644 index 0000000..805a677d --- /dev/null +++ b/storage/browser/blob/blob_storage_registry.cc @@ -0,0 +1,116 @@ +// 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. +} + +BlobStorageRegistry::Entry* BlobStorageRegistry::CreateEntry( + const std::string& uuid) { + DCHECK(!ContainsKey(blob_map_, uuid)); + Entry* entry = new Entry(1, BlobState::RESERVED); + blob_map_.add(uuid, make_scoped_ptr(entry)); + return entry; +} + +bool BlobStorageRegistry::DeleteEntry(const std::string& uuid) { + return blob_map_.erase(uuid) == 1; +} + +BlobStorageRegistry::Entry* BlobStorageRegistry::GetEntry( + const std::string& uuid) { + BlobMap::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 (blob_map_.find(uuid) == blob_map_.end() || 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; + 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) { + URLMap::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 |