1 #include "example/example.hpp" 2 3 #include <algorithm> 4 #include <cstring> 5 #include <string> 6 #include <vector> 7 8 namespace blobs 9 { 10 11 constexpr char ExampleBlobHandler::supportedPath[]; 12 13 ExampleBlob* 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 25 bool ExampleBlobHandler::canHandleBlob(const std::string& path) 26 { 27 return (path == supportedPath); 28 } 29 30 std::vector<std::string> ExampleBlobHandler::getBlobIds() 31 { 32 return {supportedPath}; 33 } 34 35 bool ExampleBlobHandler::deleteBlob(const std::string& path) 36 { 37 return false; 38 } 39 40 bool ExampleBlobHandler::stat(const std::string& path, struct BlobMeta* meta) 41 { 42 return false; 43 } 44 45 bool 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 63 std::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 89 bool 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 115 bool 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 129 bool 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 141 bool 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 157 bool 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 169