1*7ba4dab5SXin Li /*
2*7ba4dab5SXin Li * Copyright (C) 2016 The Android Open Source Project
3*7ba4dab5SXin Li *
4*7ba4dab5SXin Li * Licensed under the Apache License, Version 2.0 (the "License");
5*7ba4dab5SXin Li * you may not use this file except in compliance with the License.
6*7ba4dab5SXin Li * You may obtain a copy of the License at
7*7ba4dab5SXin Li *
8*7ba4dab5SXin Li * http://www.apache.org/licenses/LICENSE-2.0
9*7ba4dab5SXin Li *
10*7ba4dab5SXin Li * Unless required by applicable law or agreed to in writing, software
11*7ba4dab5SXin Li * distributed under the License is distributed on an "AS IS" BASIS,
12*7ba4dab5SXin Li * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*7ba4dab5SXin Li * See the License for the specific language governing permissions and
14*7ba4dab5SXin Li * limitations under the License.
15*7ba4dab5SXin Li */
16*7ba4dab5SXin Li
17*7ba4dab5SXin Li #include <nvram/core/storage.h>
18*7ba4dab5SXin Li
19*7ba4dab5SXin Li namespace nvram {
20*7ba4dab5SXin Li namespace storage {
21*7ba4dab5SXin Li namespace {
22*7ba4dab5SXin Li
23*7ba4dab5SXin Li // Maximum number of space blobs supported.
24*7ba4dab5SXin Li const int kMaxSpaces = 32;
25*7ba4dab5SXin Li
26*7ba4dab5SXin Li class StorageSlot {
27*7ba4dab5SXin Li public:
present() const28*7ba4dab5SXin Li bool present() const { return blob_.size() != 0; }
29*7ba4dab5SXin Li
Load(Blob * blob) const30*7ba4dab5SXin Li Status Load(Blob* blob) const {
31*7ba4dab5SXin Li if (blob_.size() == 0) {
32*7ba4dab5SXin Li return Status::kNotFound;
33*7ba4dab5SXin Li }
34*7ba4dab5SXin Li
35*7ba4dab5SXin Li if (!blob->Assign(blob_.data(), blob_.size())) {
36*7ba4dab5SXin Li return Status::kStorageError;
37*7ba4dab5SXin Li }
38*7ba4dab5SXin Li
39*7ba4dab5SXin Li return Status::kSuccess;
40*7ba4dab5SXin Li }
41*7ba4dab5SXin Li
Store(const Blob & blob)42*7ba4dab5SXin Li Status Store(const Blob& blob) {
43*7ba4dab5SXin Li if (!blob_.Assign(blob.data(), blob.size())) {
44*7ba4dab5SXin Li return Status::kStorageError;
45*7ba4dab5SXin Li }
46*7ba4dab5SXin Li
47*7ba4dab5SXin Li return Status::kSuccess;
48*7ba4dab5SXin Li }
49*7ba4dab5SXin Li
Delete()50*7ba4dab5SXin Li Status Delete() {
51*7ba4dab5SXin Li return blob_.Resize(0) ? Status::kSuccess : Status::kStorageError;
52*7ba4dab5SXin Li }
53*7ba4dab5SXin Li
54*7ba4dab5SXin Li private:
55*7ba4dab5SXin Li Blob blob_;
56*7ba4dab5SXin Li };
57*7ba4dab5SXin Li
58*7ba4dab5SXin Li // Stores the header blob.
59*7ba4dab5SXin Li StorageSlot g_header;
60*7ba4dab5SXin Li
61*7ba4dab5SXin Li // Stores the space blobs.
62*7ba4dab5SXin Li struct {
63*7ba4dab5SXin Li uint32_t index;
64*7ba4dab5SXin Li StorageSlot slot;
65*7ba4dab5SXin Li } g_spaces[kMaxSpaces];
66*7ba4dab5SXin Li
67*7ba4dab5SXin Li // Find the storage slot in |g_spaces| that corresponds to |index|. Returns
68*7ba4dab5SXin Li // |nullptr| if no matching slot exists.
FindSpaceSlot(uint32_t index)69*7ba4dab5SXin Li StorageSlot* FindSpaceSlot(uint32_t index) {
70*7ba4dab5SXin Li for (size_t i = 0; i < kMaxSpaces; ++i) {
71*7ba4dab5SXin Li if (g_spaces[i].slot.present() && g_spaces[i].index == index) {
72*7ba4dab5SXin Li return &g_spaces[i].slot;
73*7ba4dab5SXin Li }
74*7ba4dab5SXin Li }
75*7ba4dab5SXin Li
76*7ba4dab5SXin Li return nullptr;
77*7ba4dab5SXin Li }
78*7ba4dab5SXin Li
79*7ba4dab5SXin Li } // namespace
80*7ba4dab5SXin Li
LoadHeader(Blob * blob)81*7ba4dab5SXin Li Status LoadHeader(Blob* blob) {
82*7ba4dab5SXin Li return g_header.Load(blob);
83*7ba4dab5SXin Li }
84*7ba4dab5SXin Li
StoreHeader(const Blob & blob)85*7ba4dab5SXin Li Status StoreHeader(const Blob& blob) {
86*7ba4dab5SXin Li return g_header.Store(blob);
87*7ba4dab5SXin Li }
88*7ba4dab5SXin Li
LoadSpace(uint32_t index,Blob * blob)89*7ba4dab5SXin Li Status LoadSpace(uint32_t index, Blob* blob) {
90*7ba4dab5SXin Li StorageSlot* slot = FindSpaceSlot(index);
91*7ba4dab5SXin Li return slot ? slot->Load(blob) : Status::kNotFound;
92*7ba4dab5SXin Li }
93*7ba4dab5SXin Li
StoreSpace(uint32_t index,const Blob & blob)94*7ba4dab5SXin Li Status StoreSpace(uint32_t index, const Blob& blob) {
95*7ba4dab5SXin Li StorageSlot* slot = FindSpaceSlot(index);
96*7ba4dab5SXin Li if (slot) {
97*7ba4dab5SXin Li return slot->Store(blob);
98*7ba4dab5SXin Li }
99*7ba4dab5SXin Li
100*7ba4dab5SXin Li // Allocate a new slot.
101*7ba4dab5SXin Li for (size_t i = 0; i < kMaxSpaces; ++i) {
102*7ba4dab5SXin Li if (!g_spaces[i].slot.present()) {
103*7ba4dab5SXin Li g_spaces[i].index = index;
104*7ba4dab5SXin Li return g_spaces[i].slot.Store(blob);
105*7ba4dab5SXin Li }
106*7ba4dab5SXin Li }
107*7ba4dab5SXin Li
108*7ba4dab5SXin Li return Status::kStorageError;
109*7ba4dab5SXin Li }
110*7ba4dab5SXin Li
DeleteSpace(uint32_t index)111*7ba4dab5SXin Li Status DeleteSpace(uint32_t index) {
112*7ba4dab5SXin Li StorageSlot* slot = FindSpaceSlot(index);
113*7ba4dab5SXin Li if (slot) {
114*7ba4dab5SXin Li slot->Delete();
115*7ba4dab5SXin Li }
116*7ba4dab5SXin Li
117*7ba4dab5SXin Li return Status::kSuccess;
118*7ba4dab5SXin Li }
119*7ba4dab5SXin Li
120*7ba4dab5SXin Li } // namespace storage
121*7ba4dab5SXin Li } // namespace nvram
122