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