181 lines
4.1 KiB
C++
181 lines
4.1 KiB
C++
/*
|
|
* Copyright (C) 2016 The Android Open Source Project
|
|
*
|
|
* 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 "fake_storage.h"
|
|
|
|
#include <nvram/messages/blob.h>
|
|
#include <nvram/messages/compiler.h>
|
|
|
|
#define countof(a) (sizeof(a) / sizeof((a)[0]))
|
|
|
|
namespace nvram {
|
|
namespace storage {
|
|
|
|
namespace {
|
|
|
|
class StorageSlot {
|
|
public:
|
|
Status Load(Blob* blob) {
|
|
if (read_error_) {
|
|
return Status::kStorageError;
|
|
}
|
|
|
|
if (!present_) {
|
|
return Status::kNotFound;
|
|
}
|
|
|
|
NVRAM_CHECK(blob->Assign(blob_.data(), blob_.size()));
|
|
return Status::kSuccess;
|
|
}
|
|
|
|
Status Store(const Blob& blob) {
|
|
if (write_error_) {
|
|
return Status::kStorageError;
|
|
}
|
|
|
|
NVRAM_CHECK(blob_.Assign(blob.data(), blob.size()));
|
|
present_ = true;
|
|
return Status::kSuccess;
|
|
}
|
|
|
|
Status Delete() {
|
|
if (write_error_) {
|
|
return Status::kStorageError;
|
|
}
|
|
|
|
NVRAM_CHECK(blob_.Resize(0));
|
|
present_ = false;
|
|
return Status::kSuccess;
|
|
}
|
|
|
|
void Clear() {
|
|
present_ = false;
|
|
read_error_ = false;
|
|
write_error_ = false;
|
|
NVRAM_CHECK(blob_.Resize(0));
|
|
}
|
|
|
|
bool present() const { return present_; }
|
|
void set_present(bool present) { present_ = present; }
|
|
void set_read_error(bool error) { read_error_ = error; }
|
|
void set_write_error(bool error) { write_error_ = error; }
|
|
|
|
private:
|
|
bool present_ = false;
|
|
bool read_error_ = false;
|
|
bool write_error_ = false;
|
|
Blob blob_;
|
|
};
|
|
|
|
// Header storage.
|
|
StorageSlot g_header;
|
|
|
|
// Space blob storage.
|
|
struct SpaceStorageSlot {
|
|
uint32_t index;
|
|
StorageSlot slot;
|
|
};
|
|
|
|
SpaceStorageSlot g_spaces[256];
|
|
|
|
// Find the position in |g_spaces| corresponding to a given space |index|.
|
|
// Returns the slot pointer or |nullptr| if not found.
|
|
StorageSlot* FindSlotForIndex(uint32_t index) {
|
|
for (size_t i = 0; i < countof(g_spaces); ++i) {
|
|
if (g_spaces[i].slot.present() && g_spaces[i].index == index) {
|
|
return &g_spaces[i].slot;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
// Finds or creates the slot for |index|. Returns the slot pointer or |nullptr|
|
|
// if not found.
|
|
StorageSlot* FindOrCreateSlotForIndex(uint32_t index) {
|
|
StorageSlot* slot = FindSlotForIndex(index);
|
|
if (slot) {
|
|
return slot;
|
|
}
|
|
|
|
|
|
for (size_t i = 0; i < countof(g_spaces); ++i) {
|
|
if (!g_spaces[i].slot.present()) {
|
|
g_spaces[i].index = index;
|
|
return &g_spaces[i].slot;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
Status LoadHeader(Blob* blob) {
|
|
return g_header.Load(blob);
|
|
}
|
|
|
|
Status StoreHeader(const Blob& blob) {
|
|
return g_header.Store(blob);
|
|
}
|
|
|
|
void SetHeaderReadError(bool error) {
|
|
g_header.set_read_error(error);
|
|
}
|
|
|
|
void SetHeaderWriteError(bool error) {
|
|
g_header.set_write_error(error);
|
|
}
|
|
|
|
Status LoadSpace(uint32_t index, Blob* blob) {
|
|
StorageSlot* slot = FindSlotForIndex(index);
|
|
return slot ? slot->Load(blob) : Status::kNotFound;
|
|
}
|
|
|
|
Status StoreSpace(uint32_t index, const Blob& blob) {
|
|
StorageSlot* slot = FindOrCreateSlotForIndex(index);
|
|
return slot ? slot->Store(blob) : Status::kStorageError;
|
|
}
|
|
|
|
Status DeleteSpace(uint32_t index) {
|
|
StorageSlot* slot = FindSlotForIndex(index);
|
|
return slot ? slot->Delete() : Status::kNotFound;
|
|
}
|
|
|
|
void Clear() {
|
|
g_header.Clear();
|
|
for (size_t i = 0; i < countof(g_spaces); ++i) {
|
|
g_spaces[i].slot.Clear();
|
|
}
|
|
}
|
|
|
|
void SetSpaceReadError(uint32_t index, bool error) {
|
|
StorageSlot* slot = FindOrCreateSlotForIndex(index);
|
|
if (slot) {
|
|
slot->set_read_error(error);
|
|
}
|
|
}
|
|
|
|
void SetSpaceWriteError(uint32_t index, bool error) {
|
|
StorageSlot* slot = FindOrCreateSlotForIndex(index);
|
|
if (slot) {
|
|
slot->set_write_error(error);
|
|
}
|
|
}
|
|
|
|
} // namespace storage
|
|
} // namespace nvram
|