1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "fake_storage.h" 18 19#include <nvram/messages/blob.h> 20#include <nvram/messages/compiler.h> 21 22#define countof(a) (sizeof(a) / sizeof((a)[0])) 23 24namespace nvram { 25namespace storage { 26 27namespace { 28 29class StorageSlot { 30 public: 31 Status Load(Blob* blob) { 32 if (read_error_) { 33 return Status::kStorageError; 34 } 35 36 if (!present_) { 37 return Status::kNotFound; 38 } 39 40 NVRAM_CHECK(blob->Assign(blob_.data(), blob_.size())); 41 return Status::kSuccess; 42 } 43 44 Status Store(const Blob& blob) { 45 if (write_error_) { 46 return Status::kStorageError; 47 } 48 49 NVRAM_CHECK(blob_.Assign(blob.data(), blob.size())); 50 present_ = true; 51 return Status::kSuccess; 52 } 53 54 Status Delete() { 55 if (write_error_) { 56 return Status::kStorageError; 57 } 58 59 NVRAM_CHECK(blob_.Resize(0)); 60 present_ = false; 61 return Status::kSuccess; 62 } 63 64 void Clear() { 65 present_ = false; 66 read_error_ = false; 67 write_error_ = false; 68 NVRAM_CHECK(blob_.Resize(0)); 69 } 70 71 bool present() const { return present_; } 72 void set_present(bool present) { present_ = present; } 73 void set_read_error(bool error) { read_error_ = error; } 74 void set_write_error(bool error) { write_error_ = error; } 75 76 private: 77 bool present_ = false; 78 bool read_error_ = false; 79 bool write_error_ = false; 80 Blob blob_; 81}; 82 83// Header storage. 84StorageSlot g_header; 85 86// Space blob storage. 87struct SpaceStorageSlot { 88 uint32_t index; 89 StorageSlot slot; 90}; 91 92SpaceStorageSlot g_spaces[256]; 93 94// Find the position in |g_spaces| corresponding to a given space |index|. 95// Returns the slot pointer or |nullptr| if not found. 96StorageSlot* FindSlotForIndex(uint32_t index) { 97 for (size_t i = 0; i < countof(g_spaces); ++i) { 98 if (g_spaces[i].slot.present() && g_spaces[i].index == index) { 99 return &g_spaces[i].slot; 100 } 101 } 102 103 return nullptr; 104} 105 106// Finds or creates the slot for |index|. Returns the slot pointer or |nullptr| 107// if not found. 108StorageSlot* FindOrCreateSlotForIndex(uint32_t index) { 109 StorageSlot* slot = FindSlotForIndex(index); 110 if (slot) { 111 return slot; 112 } 113 114 115 for (size_t i = 0; i < countof(g_spaces); ++i) { 116 if (!g_spaces[i].slot.present()) { 117 g_spaces[i].index = index; 118 return &g_spaces[i].slot; 119 } 120 } 121 122 return nullptr; 123} 124 125} // namespace 126 127Status LoadHeader(Blob* blob) { 128 return g_header.Load(blob); 129} 130 131Status StoreHeader(const Blob& blob) { 132 return g_header.Store(blob); 133} 134 135void SetHeaderReadError(bool error) { 136 g_header.set_read_error(error); 137} 138 139void SetHeaderWriteError(bool error) { 140 g_header.set_write_error(error); 141} 142 143Status LoadSpace(uint32_t index, Blob* blob) { 144 StorageSlot* slot = FindSlotForIndex(index); 145 return slot ? slot->Load(blob) : Status::kNotFound; 146} 147 148Status StoreSpace(uint32_t index, const Blob& blob) { 149 StorageSlot* slot = FindOrCreateSlotForIndex(index); 150 return slot ? slot->Store(blob) : Status::kStorageError; 151} 152 153Status DeleteSpace(uint32_t index) { 154 StorageSlot* slot = FindSlotForIndex(index); 155 return slot ? slot->Delete() : Status::kNotFound; 156} 157 158void Clear() { 159 g_header.Clear(); 160 for (size_t i = 0; i < countof(g_spaces); ++i) { 161 g_spaces[i].slot.Clear(); 162 } 163} 164 165void SetSpaceReadError(uint32_t index, bool error) { 166 StorageSlot* slot = FindOrCreateSlotForIndex(index); 167 if (slot) { 168 slot->set_read_error(error); 169 } 170} 171 172void SetSpaceWriteError(uint32_t index, bool error) { 173 StorageSlot* slot = FindOrCreateSlotForIndex(index); 174 if (slot) { 175 slot->set_write_error(error); 176 } 177} 178 179} // namespace storage 180} // namespace nvram 181