blob: 66c822779b695972167892a5ff5ebdd17be20e93 [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 Venturec0f499b2018-09-14 17:57:42 -07005#include <string>
6#include <vector>
7
8namespace blobs
9{
10
11constexpr char ExampleBlobHandler::supportedPath[];
12
13ExampleBlob* ExampleBlobHandler::getSession(uint16_t id)
14{
15 auto search = sessions.find(id);
16 if (search == sessions.end())
17 {
18 return nullptr;
19 }
20 /* Not thread-safe, however, the blob handler deliberately assumes serial
21 * execution. */
22 return &search->second;
23}
24
25bool ExampleBlobHandler::canHandleBlob(const std::string& path)
26{
27 return (path == supportedPath);
28}
29
30std::vector<std::string> ExampleBlobHandler::getBlobIds()
31{
32 return {supportedPath};
33}
34
35bool ExampleBlobHandler::deleteBlob(const std::string& path)
36{
37 return false;
38}
39
40bool ExampleBlobHandler::stat(const std::string& path, struct BlobMeta* meta)
41{
42 return false;
43}
44
45bool ExampleBlobHandler::open(uint16_t session, uint16_t flags,
46 const std::string& path)
47{
48 if (!canHandleBlob(path))
49 {
50 return false;
51 }
52
53 auto findSess = sessions.find(session);
54 if (findSess != sessions.end())
55 {
56 /* This session is already active. */
57 return false;
58 }
59 sessions[session] = ExampleBlob(session, flags);
60 return true;
61}
62
63std::vector<uint8_t> ExampleBlobHandler::read(uint16_t session, uint32_t offset,
64 uint32_t requestedSize)
65{
66 ExampleBlob* sess = getSession(session);
67 if (!sess)
68 {
69 return std::vector<uint8_t>();
70 }
71
72 /* Is the offset beyond the array? */
73 if (offset >= sizeof(sess->buffer))
74 {
75 return std::vector<uint8_t>();
76 }
77
78 /* Determine how many bytes we can read from the offset.
79 * In this case, if they read beyond "size" we allow it.
80 */
81 uint32_t remain = sizeof(sess->buffer) - offset;
82 uint32_t numBytes = std::min(remain, requestedSize);
83 /* Copy the bytes! */
84 std::vector<uint8_t> result(numBytes);
85 std::memcpy(result.data(), &sess->buffer[offset], numBytes);
86 return result;
87}
88
89bool ExampleBlobHandler::write(uint16_t session, uint32_t offset,
90 const std::vector<uint8_t>& data)
91{
92 ExampleBlob* sess = getSession(session);
93 if (!sess)
94 {
95 return false;
96 }
97 /* Is the offset beyond the array? */
98 if (offset >= sizeof(sess->buffer))
99 {
100 return false;
101 }
102 /* Determine whether all their bytes will fit. */
103 uint32_t remain = sizeof(sess->buffer) - offset;
104 if (data.size() > remain)
105 {
106 return false;
107 }
108 sess->length =
109 std::max(offset + data.size(),
110 static_cast<std::vector<uint8_t>::size_type>(sess->length));
111 std::memcpy(&sess->buffer[offset], data.data(), data.size());
112 return true;
113}
114
115bool ExampleBlobHandler::commit(uint16_t session,
116 const std::vector<uint8_t>& data)
117{
118 ExampleBlob* sess = getSession(session);
119 if (!sess)
120 {
121 return false;
122 }
123
124 /* Do something with the staged data!. */
125
126 return false;
127}
128
129bool ExampleBlobHandler::close(uint16_t session)
130{
131 ExampleBlob* sess = getSession(session);
132 if (!sess)
133 {
134 return false;
135 }
136
137 sessions.erase(session);
138 return true;
139}
140
141bool ExampleBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
142{
143 ExampleBlob* sess = getSession(session);
144 if (!sess)
145 {
146 return false;
147 }
148 if (!meta)
149 {
150 return false;
151 }
152 meta->size = sess->length;
153 meta->blobState = sess->state;
154 return true;
155}
156
157bool ExampleBlobHandler::expire(uint16_t session)
158{
159 ExampleBlob* sess = getSession(session);
160 if (!sess)
161 {
162 return false;
163 }
164 /* TODO: implement session expiration behavior. */
165 return false;
166}
167
168} // namespace blobs