1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
#include "example/example.hpp"
#include <algorithm>
#include <blobs-ipmid/manager.hpp>
#include <cstring>
#include <memory>
#include <phosphor-logging/log.hpp>
#include <string>
#include <vector>
namespace blobs
{
using namespace phosphor::logging;
constexpr char ExampleBlobHandler::supportedPath[];
ExampleBlob* ExampleBlobHandler::getSession(uint16_t id)
{
auto search = sessions.find(id);
if (search == sessions.end())
{
return nullptr;
}
/* Not thread-safe, however, the blob handler deliberately assumes serial
* execution. */
return &search->second;
}
bool ExampleBlobHandler::canHandleBlob(const std::string& path)
{
return (path == supportedPath);
}
std::vector<std::string> ExampleBlobHandler::getBlobIds()
{
return {supportedPath};
}
bool ExampleBlobHandler::deleteBlob(const std::string& path)
{
return false;
}
bool ExampleBlobHandler::stat(const std::string& path, struct BlobMeta* meta)
{
return false;
}
bool ExampleBlobHandler::open(uint16_t session, uint16_t flags,
const std::string& path)
{
if (!canHandleBlob(path))
{
return false;
}
auto findSess = sessions.find(session);
if (findSess != sessions.end())
{
/* This session is already active. */
return false;
}
sessions[session] = ExampleBlob(session, flags);
return true;
}
std::vector<uint8_t> ExampleBlobHandler::read(uint16_t session, uint32_t offset,
uint32_t requestedSize)
{
ExampleBlob* sess = getSession(session);
if (!sess)
{
return std::vector<uint8_t>();
}
/* Is the offset beyond the array? */
if (offset >= sizeof(sess->buffer))
{
return std::vector<uint8_t>();
}
/* Determine how many bytes we can read from the offset.
* In this case, if they read beyond "size" we allow it.
*/
uint32_t remain = sizeof(sess->buffer) - offset;
uint32_t numBytes = std::min(remain, requestedSize);
/* Copy the bytes! */
std::vector<uint8_t> result(numBytes);
std::memcpy(result.data(), &sess->buffer[offset], numBytes);
return result;
}
bool ExampleBlobHandler::write(uint16_t session, uint32_t offset,
const std::vector<uint8_t>& data)
{
ExampleBlob* sess = getSession(session);
if (!sess)
{
return false;
}
/* Is the offset beyond the array? */
if (offset >= sizeof(sess->buffer))
{
return false;
}
/* Determine whether all their bytes will fit. */
uint32_t remain = sizeof(sess->buffer) - offset;
if (data.size() > remain)
{
return false;
}
sess->length =
std::max(offset + data.size(),
static_cast<std::vector<uint8_t>::size_type>(sess->length));
std::memcpy(&sess->buffer[offset], data.data(), data.size());
return true;
}
bool ExampleBlobHandler::writeMeta(uint16_t session, uint32_t offset,
const std::vector<uint8_t>& data)
{
/* Not supported. */
return false;
}
bool ExampleBlobHandler::commit(uint16_t session,
const std::vector<uint8_t>& data)
{
ExampleBlob* sess = getSession(session);
if (!sess)
{
return false;
}
/* Do something with the staged data!. */
return false;
}
bool ExampleBlobHandler::close(uint16_t session)
{
ExampleBlob* sess = getSession(session);
if (!sess)
{
return false;
}
sessions.erase(session);
return true;
}
bool ExampleBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
{
ExampleBlob* sess = getSession(session);
if (!sess)
{
return false;
}
if (!meta)
{
return false;
}
meta->size = sess->length;
meta->blobState = sess->state;
return true;
}
bool ExampleBlobHandler::expire(uint16_t session)
{
ExampleBlob* sess = getSession(session);
if (!sess)
{
return false;
}
/* TODO: implement session expiration behavior. */
return false;
}
void setupExampleHandler() __attribute__((constructor));
void setupExampleHandler()
{
// You don't need to do anything in the constructor.
}
} // namespace blobs
/**
* This method is required by the blob manager.
*
* It is called to grab a handler for registering the blob handler instance.
*/
std::unique_ptr<blobs::GenericBlobInterface> createHandler()
{
return std::make_unique<blobs::ExampleBlobHandler>();
}
|