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..028d87bebf5a05ff03fe14c8e82398e6c86de490 |
--- /dev/null |
+++ b/storage/browser/blob/blob_storage_registry.cc |
@@ -0,0 +1,162 @@ |
+// 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 "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 "storage/browser/blob/blob_storage_registry.h" |
michaeln
2015/08/18 02:25:46
you can put the main include up top followed by a
dmurph
2015/09/15 00:54:34
Whoops, thanks.
|
+#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::BlobRegistryEntry::BlobRegistryEntry(int refcount, |
+ BlobState state) |
+ : refcount(refcount), state(state), flags(0) {} |
+ |
+BlobStorageRegistry::BlobRegistryEntry::~BlobRegistryEntry() {} |
+ |
+bool BlobStorageRegistry::BlobRegistryEntry::IsFlagSet(int flag) { |
+ return ((flags & flag) != 0); |
michaeln
2015/08/18 02:25:46
probably can inline the flag getters/settings and
dmurph
2015/09/15 00:54:34
done.
|
+} |
+ |
+void BlobStorageRegistry::BlobRegistryEntry::SetFlag(int flag) { |
+ flags |= flag; |
+} |
+ |
+void BlobStorageRegistry::BlobRegistryEntry::UnsetFlag(int flag) { |
+ flags &= !flag; |
michaeln
2015/08/18 02:25:46
do you want the bitwise operator here?
dmurph
2015/09/15 00:54:34
Yes. This is the current behavior in the system. I
michaeln
2015/10/09 02:16:14
Why, your changing most all other aspects of the c
dmurph
2015/10/10 00:11:33
Done.
|
+} |
+ |
+BlobStorageRegistry::BlobStorageRegistry() {} |
+ |
+BlobStorageRegistry::~BlobStorageRegistry() { |
+ auto begin = blob_map_.begin(); |
+ auto end = blob_map_.end(); |
+ while (begin != end) { |
michaeln
2015/08/18 02:25:46
this is oddly formed for each loop, would a for (c
dmurph
2015/09/15 00:54:34
Done.
|
+ auto temp = begin; |
+ ++begin; |
+ BlobRegistryEntry* entry = temp->second; |
kinuko
2015/08/14 10:12:18
scoped_ptr<BlobRegistryEntry> entry(temp->second);
dmurph
2015/09/15 00:54:34
Done.
|
+ // We need to make sure we cleanup all of the callbacks so we don't leave |
+ // any dangling URL requests around. |
+ if (entry && !entry->construction_complete_callbacks.empty()) { |
michaeln
2015/08/18 02:25:46
Can |entry| ever be null? i don't see how it can?
dmurph
2015/09/15 00:54:34
Nope. Removed.
|
+ for (const auto& callback : entry->construction_complete_callbacks) { |
+ base::MessageLoop::current()->PostTask(FROM_HERE, |
+ base::Bind(callback, false)); |
+ } |
+ } |
+ delete temp->second; |
+ } |
+} |
+ |
+BlobStorageRegistry::BlobRegistryEntry* BlobStorageRegistry::RegisterBlobUUID( |
+ const std::string& uuid) { |
+ if (blob_map_.find(uuid) != blob_map_.end()) |
kinuko
2015/08/14 10:12:18
nit: prefer ContainsKey() in stl_util.h in general
michaeln
2015/08/18 02:25:46
Is attempting to reuse a uuid ever expected? I can
dmurph
2015/09/15 00:54:34
Tests accidentally do this a lot, as I've done mys
michaeln
2015/10/09 02:16:14
Fix the test, it's buggy.
dmurph
2015/10/10 00:11:33
Ok, I made it a dcheck
|
+ return nullptr; |
+ auto* entry = new BlobRegistryEntry(1, BlobState::RESERVED); |
+ blob_map_[uuid] = entry; |
+ return entry; |
+} |
+ |
+bool BlobStorageRegistry::RemoveBlobEntry(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::IsUUIDRegistered(const std::string& uuid) const { |
+ return blob_map_.find(uuid) != blob_map_.end(); |
+} |
+ |
+BlobStorageRegistry::BlobRegistryEntry* BlobStorageRegistry::GetBlobEntry( |
+ const std::string& uuid) { |
+ BlobMap::iterator found = blob_map_.find(uuid); |
+ if (found == blob_map_.end()) { |
+ return nullptr; |
+ } |
+ return found->second; |
+} |
+ |
+BlobState BlobStorageRegistry::GetBlobState(const std::string& uuid) const { |
+ BlobMap::const_iterator found = blob_map_.find(uuid); |
+ return found == blob_map_.end() ? BlobState::UNKNOWN : found->second->state; |
+} |
+ |
+bool BlobStorageRegistry::TestAndSetState(const std::string& uuid, |
+ BlobState expected, |
+ BlobState set) { |
+ BlobRegistryEntry* entry = GetBlobEntry(uuid); |
+ if (!entry || entry->state != expected) |
+ return false; |
+ entry->state = set; |
+ return true; |
+} |
+ |
+bool BlobStorageRegistry::RegisterURLMapping(const GURL& blob_url, |
+ const std::string& uuid) { |
+ if (!IsUUIDRegistered(uuid) || IsURLMapped(blob_url)) |
+ return false; |
+ url_to_uuid_[blob_url] = uuid; |
+ return true; |
+} |
+ |
+bool BlobStorageRegistry::RemoveURLMapping(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 url_to_uuid_.find(blob_url) != url_to_uuid_.end(); |
kinuko
2015/08/14 10:12:18
nit: ContainsKey
dmurph
2015/09/15 00:54:34
Done.
|
+} |
+ |
+BlobStorageRegistry::BlobRegistryEntry* |
+BlobStorageRegistry::GetBlobEntryFromURL(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; |
+ } |
+ BlobRegistryEntry* entry = GetBlobEntry(found->second); |
+ if (entry && uuid) { |
+ uuid->assign(found->second); |
+ } |
+ return entry; |
+} |
+ |
+} // namespace storage |