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