blob: 7bc46674b9cb75ed72850b52a26b209b10063941 [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/storage/savegame.h"
#include <algorithm>
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
namespace cobalt {
namespace storage {
namespace {
const char kDefaultSavegamePath[] = ".cobalt.sav";
FilePath GetSavegamePath() {
FilePath home_dir;
bool ok = PathService::Get(base::DIR_HOME, &home_dir);
DCHECK_EQ(true, ok);
return home_dir.Append(kDefaultSavegamePath);
}
} // namespace
// Savegame implementation that writes to a regular file, using file_util.
class SavegameFile : public Savegame {
public:
explicit SavegameFile(const Options& options);
~SavegameFile() OVERRIDE;
bool PlatformRead(size_t max_to_read, ByteVector* bytes) OVERRIDE;
bool PlatformWrite(const ByteVector& bytes) OVERRIDE;
bool PlatformDelete() OVERRIDE;
private:
FilePath savegame_path_;
};
SavegameFile::SavegameFile(const Options& options) : Savegame(options) {
if (options.path_override.length() > 0) {
savegame_path_ = FilePath(options.path_override);
} else {
savegame_path_ = GetSavegamePath();
}
}
SavegameFile::~SavegameFile() {
if (options_.delete_on_destruction) {
Delete();
}
}
bool SavegameFile::PlatformRead(ByteVector* bytes_ptr, size_t max_to_read) {
if (!file_util::PathExists(savegame_path_)) {
return false;
}
int64 file_size;
if (!file_util::GetFileSize(savegame_path_, &file_size)) {
DLOG(WARNING) << "GetFileSize of " << savegame_path_.value() << " failed";
return false;
}
if (max_to_read < static_cast<size_t>(file_size) {
DLOG(WARNING) << "Savegame larger than max allowed size";
return false;
}
ByteVector& bytes = *bytes_ptr;
bytes.resize(static_cast<size_t>(file_size));
if (!bytes.empty()) {
int bytes_read =
file_util::ReadFile(savegame_path_, reinterpret_cast<char*>(&bytes[0]),
static_cast<int>(file_size));
bytes.resize(static_cast<size_t>(std::max(0, bytes_read)));
return bytes_read == file_size;
} else {
return true;
}
}
bool SavegameFile::PlatformWrite(const ByteVector& bytes) {
int byte_count = static_cast<int>(bytes.size());
int bytes_written = file_util::WriteFile(
savegame_path_, reinterpret_cast<const char*>(&bytes[0]), byte_count);
return bytes_written == byte_count;
}
bool SavegameFile::PlatformDelete() {
if (file_util::PathExists(savegame_path_)) {
return file_util::Delete(savegame_path_, false /* recursive */);
} else {
return false;
}
}
// static
scoped_ptr<Savegame> Savegame::Create(const Options& options) {
scoped_ptr<Savegame> savegame(new SavegameFile(options));
return savegame.Pass();
}
} // namespace storage
} // namespace cobalt