blob: 66500f4602208f9106b11151018c723b28088d88 [file] [log] [blame]
#include "handler.hpp"
#include <algorithm>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
using std::size_t;
using std::uint16_t;
using std::uint32_t;
using std::uint64_t;
using std::uint8_t;
namespace blobs
{
namespace internal
{
/**
* @brief: Get baseId from a blob id string
* @param blobId: Input blob id which is expected to only contain alphanumerical
* characters and '/'.
* @returns: the baseId containing the blobId, stripping all contents from the
* last '/'. If no '/' is present, an empty string is returned.
*/
static std::string getBaseFromId(const std::string& blobId)
{
return blobId.substr(0, blobId.find_last_of('/') + 1);
}
} // namespace internal
void BinaryStoreBlobHandler::addNewBinaryStore(
std::unique_ptr<binstore::BinaryStoreInterface> store)
{
// TODO: this is a very rough measure to test the mock interface for now.
stores_[store->getBaseBlobId()] = std::move(store);
}
bool BinaryStoreBlobHandler::canHandleBlob(const std::string& path)
{
auto base = internal::getBaseFromId(path);
if (base.empty() || base == path)
{
/* Operations on baseId itself or an empty base is not allowed */
return false;
}
return std::any_of(stores_.begin(), stores_.end(),
[&](const auto& baseStorePair) {
return base == baseStorePair.second->getBaseBlobId();
});
}
std::vector<std::string> BinaryStoreBlobHandler::getBlobIds()
{
std::vector<std::string> result;
for (const auto& baseStorePair : stores_)
{
const auto& ids = baseStorePair.second->getBlobIds();
result.insert(result.end(), ids.begin(), ids.end());
}
return result;
}
bool BinaryStoreBlobHandler::deleteBlob(const std::string& path)
{
auto it = stores_.find(internal::getBaseFromId(path));
if (it == stores_.end())
{
return false;
}
return it->second->deleteBlob(path);
}
bool BinaryStoreBlobHandler::stat(const std::string& path,
struct BlobMeta* meta)
{
auto it = stores_.find(internal::getBaseFromId(path));
if (it == stores_.end())
{
return false;
}
return it->second->stat(meta);
}
bool BinaryStoreBlobHandler::open(uint16_t session, uint16_t flags,
const std::string& path)
{
if (!canHandleBlob(path))
{
return false;
}
auto found = sessions_.find(session);
if (found != sessions_.end())
{
/* This session is already active */
return false;
}
const auto& base = internal::getBaseFromId(path);
if (stores_.find(base) == stores_.end())
{
return false;
}
if (!stores_[base]->openOrCreateBlob(path, flags))
{
return false;
}
sessions_[session] = stores_[base].get();
return true;
}
std::vector<uint8_t> BinaryStoreBlobHandler::read(uint16_t session,
uint32_t offset,
uint32_t requestedSize)
{
auto it = sessions_.find(session);
if (it == sessions_.end())
{
return std::vector<uint8_t>();
}
return it->second->read(offset, requestedSize);
}
bool BinaryStoreBlobHandler::write(uint16_t session, uint32_t offset,
const std::vector<uint8_t>& data)
{
auto it = sessions_.find(session);
if (it == sessions_.end())
{
return false;
}
return it->second->write(offset, data);
}
bool BinaryStoreBlobHandler::writeMeta(uint16_t session, uint32_t offset,
const std::vector<uint8_t>& data)
{
/* Binary store handler doesn't support write meta */
return false;
}
bool BinaryStoreBlobHandler::commit(uint16_t session,
const std::vector<uint8_t>& data)
{
auto it = sessions_.find(session);
if (it == sessions_.end())
{
return false;
}
return it->second->commit();
}
bool BinaryStoreBlobHandler::close(uint16_t session)
{
auto it = sessions_.find(session);
if (it == sessions_.end())
{
return false;
}
if (!it->second->close())
{
return false;
}
sessions_.erase(session);
return true;
}
bool BinaryStoreBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
{
auto it = sessions_.find(session);
if (it == sessions_.end())
{
return false;
}
return it->second->stat(meta);
}
bool BinaryStoreBlobHandler::expire(uint16_t session)
{
return close(session);
}
} // namespace blobs