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