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 |