• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 namespace nvram {
25 namespace storage {
26 
27 namespace {
28 
29 class StorageSlot {
30  public:
Load(Blob * blob)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 
Store(const Blob & blob)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 
Delete()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 
Clear()64   void Clear() {
65     present_ = false;
66     read_error_ = false;
67     write_error_ = false;
68     NVRAM_CHECK(blob_.Resize(0));
69   }
70 
present() const71   bool present() const { return present_; }
set_present(bool present)72   void set_present(bool present) { present_ = present; }
set_read_error(bool error)73   void set_read_error(bool error) { read_error_ = error; }
set_write_error(bool 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.
84 StorageSlot g_header;
85 
86 // Space blob storage.
87 struct SpaceStorageSlot {
88   uint32_t index;
89   StorageSlot slot;
90 };
91 
92 SpaceStorageSlot 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.
FindSlotForIndex(uint32_t index)96 StorageSlot* 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.
FindOrCreateSlotForIndex(uint32_t index)108 StorageSlot* 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 
LoadHeader(Blob * blob)127 Status LoadHeader(Blob* blob) {
128   return g_header.Load(blob);
129 }
130 
StoreHeader(const Blob & blob)131 Status StoreHeader(const Blob& blob) {
132   return g_header.Store(blob);
133 }
134 
SetHeaderReadError(bool error)135 void SetHeaderReadError(bool error) {
136   g_header.set_read_error(error);
137 }
138 
SetHeaderWriteError(bool error)139 void SetHeaderWriteError(bool error) {
140   g_header.set_write_error(error);
141 }
142 
LoadSpace(uint32_t index,Blob * blob)143 Status LoadSpace(uint32_t index, Blob* blob) {
144   StorageSlot* slot = FindSlotForIndex(index);
145   return slot ? slot->Load(blob) : Status::kNotFound;
146 }
147 
StoreSpace(uint32_t index,const Blob & blob)148 Status StoreSpace(uint32_t index, const Blob& blob) {
149   StorageSlot* slot = FindOrCreateSlotForIndex(index);
150   return slot ? slot->Store(blob) : Status::kStorageError;
151 }
152 
DeleteSpace(uint32_t index)153 Status DeleteSpace(uint32_t index) {
154   StorageSlot* slot = FindSlotForIndex(index);
155   return slot ? slot->Delete() : Status::kNotFound;
156 }
157 
Clear()158 void 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 
SetSpaceReadError(uint32_t index,bool error)165 void SetSpaceReadError(uint32_t index, bool error) {
166   StorageSlot* slot = FindOrCreateSlotForIndex(index);
167   if (slot) {
168     slot->set_read_error(error);
169   }
170 }
171 
SetSpaceWriteError(uint32_t index,bool error)172 void 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