| 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..805a677d898ef84e420009205607e28aa61d6c25
|
| --- /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
|
|
|