| Index: webkit/dom_storage/dom_storage_area.cc
|
| diff --git a/webkit/dom_storage/dom_storage_area.cc b/webkit/dom_storage/dom_storage_area.cc
|
| index c152f3fa44aecbeb5de38e045c2429911be3e86f..5f2db657f820d1c478dbb60eff1cf9299919a5ec 100644
|
| --- a/webkit/dom_storage/dom_storage_area.cc
|
| +++ b/webkit/dom_storage/dom_storage_area.cc
|
| @@ -5,6 +5,7 @@
|
| #include "webkit/dom_storage/dom_storage_area.h"
|
| #include "webkit/dom_storage/dom_storage_map.h"
|
| #include "webkit/dom_storage/dom_storage_namespace.h"
|
| +#include "webkit/fileapi/file_system_util.h"
|
|
|
| namespace dom_storage {
|
|
|
| @@ -13,44 +14,81 @@ DomStorageArea::DomStorageArea(
|
| const FilePath& directory, DomStorageTaskRunner* task_runner)
|
| : namespace_id_(namespace_id), origin_(origin),
|
| directory_(directory), task_runner_(task_runner),
|
| - map_(new DomStorageMap()) {
|
| + map_(new DomStorageMap()),
|
| + backing_(NULL),
|
| + initial_import_done_(false),
|
| + clear_all_next_sync_(false) {
|
| +
|
| + if (namespace_id == kLocalStorageNamespaceId && !directory.empty()) {
|
| + FilePath path = directory.Append(DatabaseFileNameFromOrigin(origin_));
|
| + backing_.reset(new DomStorageDatabase(path));
|
| + } else {
|
| + // Not a local storage area or no directory specified for backing
|
| + // database, (i.e. it's an incognito profile).
|
| + initial_import_done_ = true;
|
| + }
|
| }
|
|
|
| DomStorageArea::~DomStorageArea() {
|
| }
|
|
|
| unsigned DomStorageArea::Length() {
|
| + InitialImportIfNeeded();
|
| return map_->Length();
|
| }
|
|
|
| NullableString16 DomStorageArea::Key(unsigned index) {
|
| + InitialImportIfNeeded();
|
| return map_->Key(index);
|
| }
|
|
|
| NullableString16 DomStorageArea::GetItem(const string16& key) {
|
| + InitialImportIfNeeded();
|
| return map_->GetItem(key);
|
| }
|
|
|
| bool DomStorageArea::SetItem(
|
| const string16& key, const string16& value,
|
| NullableString16* old_value) {
|
| + InitialImportIfNeeded();
|
| +
|
| if (!map_->HasOneRef())
|
| map_ = map_->DeepCopy();
|
| - return map_->SetItem(key, value, old_value);
|
| + bool success = map_->SetItem(key, value, old_value);
|
| + if (success && backing_.get()) {
|
| + items_to_sync_[key] = NullableString16(value, false);
|
| + SyncToBacking();
|
| + }
|
| + return success;
|
| }
|
|
|
| bool DomStorageArea::RemoveItem(
|
| const string16& key,
|
| string16* old_value) {
|
| + InitialImportIfNeeded();
|
| if (!map_->HasOneRef())
|
| map_ = map_->DeepCopy();
|
| - return map_->RemoveItem(key, old_value);
|
| + bool success = map_->RemoveItem(key, old_value);
|
| + if (success && backing_.get()) {
|
| + items_to_sync_[key] = NullableString16(true);
|
| + SyncToBacking();
|
| + }
|
| + return success;
|
| }
|
|
|
| bool DomStorageArea::Clear() {
|
| + InitialImportIfNeeded();
|
| if (map_->Length() == 0)
|
| return false;
|
| +
|
| map_ = new DomStorageMap();
|
| +
|
| + if (backing_.get()) {
|
| + items_to_sync_.clear();
|
| + clear_all_next_sync_ = true;
|
| + SyncToBacking();
|
| + }
|
| +
|
| return true;
|
| }
|
|
|
| @@ -58,10 +96,44 @@ DomStorageArea* DomStorageArea::ShallowCopy(int64 destination_namespace_id) {
|
| DCHECK_NE(kLocalStorageNamespaceId, namespace_id_);
|
| DCHECK_NE(kLocalStorageNamespaceId, destination_namespace_id);
|
| // SessionNamespaces aren't backed by files on disk.
|
| + DCHECK(!backing_.get());
|
| +
|
| DomStorageArea* copy = new DomStorageArea(destination_namespace_id, origin_,
|
| FilePath(), task_runner_);
|
| copy->map_ = map_;
|
| return copy;
|
| }
|
|
|
| +void DomStorageArea::InitialImportIfNeeded() {
|
| + if (initial_import_done_)
|
| + return;
|
| +
|
| + DCHECK_EQ(kLocalStorageNamespaceId, namespace_id_);
|
| + DCHECK(backing_.get());
|
| +
|
| + ValuesMap initial_values;
|
| + backing_->ReadAllValues(&initial_values);
|
| + map_->SwapValues(&initial_values);
|
| + initial_import_done_ = true;
|
| +}
|
| +
|
| +void DomStorageArea::SyncToBacking() {
|
| + DCHECK_EQ(kLocalStorageNamespaceId, namespace_id_);
|
| + DCHECK(backing_.get());
|
| +
|
| + if (!clear_all_next_sync_ && items_to_sync_.empty())
|
| + return;
|
| +
|
| + backing_->CommitChanges(clear_all_next_sync_, items_to_sync_);
|
| + clear_all_next_sync_ = false;
|
| + items_to_sync_.clear();
|
| +}
|
| +
|
| +// static
|
| +FilePath DomStorageArea::DatabaseFileNameFromOrigin(const GURL& origin) {
|
| + std::string filename = fileapi::GetOriginIdentifierFromURL(origin)
|
| + + ".localstorage";
|
| + return FilePath().AppendASCII(filename);
|
| +}
|
| +
|
| } // namespace dom_storage
|
|
|