| #pragma once |
| |
| #include "binarystore_interface.hpp" |
| #include "sys_file.hpp" |
| |
| #include <unistd.h> |
| |
| #include <blobs-ipmid/blobs.hpp> |
| #include <cstdint> |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #include "binaryblob.pb.h" |
| |
| using std::size_t; |
| using std::uint16_t; |
| using std::uint32_t; |
| using std::uint64_t; |
| using std::uint8_t; |
| |
| namespace binstore |
| { |
| |
| /** |
| * @class BinaryStore instantiates a concrete implementation of |
| * BinaryStoreInterface. The dependency on file is injected through its |
| * constructor. |
| */ |
| class BinaryStore : public BinaryStoreInterface |
| { |
| public: |
| /* |CommitState| differs slightly with |StateFlags| in blob.hpp, |
| * and thus is defined in the OEM space (bit 8 - 15). User can call stat() |
| * to query the |CommitState| of the blob path. */ |
| enum CommitState |
| { |
| Dirty = (1 << 8), // In-memory data might not match persisted data |
| Clean = (1 << 9), // In-memory data matches persisted data |
| Uninitialized = (1 << 10), // Cannot find persisted data |
| CommitError = (1 << 11) // Error happened during committing |
| }; |
| |
| BinaryStore() = delete; |
| BinaryStore(const std::string& baseBlobId, std::unique_ptr<SysFile> file, |
| std::optional<uint32_t> maxSize = std::nullopt) : |
| baseBlobId_(baseBlobId), |
| file_(std::move(file)), maxSize(maxSize) |
| { |
| blob_.set_blob_base_id(baseBlobId_); |
| if (maxSize) |
| { |
| blob_.set_max_size_bytes(*maxSize); |
| } |
| } |
| |
| BinaryStore(std::unique_ptr<SysFile> file, bool readOnly = false, |
| std::optional<uint32_t> maxSize = std::nullopt) : |
| readOnly_{readOnly}, |
| file_(std::move(file)), maxSize(maxSize) |
| { |
| if (maxSize) |
| { |
| blob_.set_max_size_bytes(*maxSize); |
| } |
| } |
| |
| ~BinaryStore() = default; |
| |
| BinaryStore(const BinaryStore&) = delete; |
| BinaryStore& operator=(const BinaryStore&) = delete; |
| BinaryStore(BinaryStore&&) = default; |
| BinaryStore& operator=(BinaryStore&&) = default; |
| |
| std::string getBaseBlobId() const override; |
| bool setBaseBlobId(const std::string& baseBlobId) override; |
| std::vector<std::string> getBlobIds() const override; |
| bool openOrCreateBlob(const std::string& blobId, uint16_t flags) override; |
| bool deleteBlob(const std::string& blobId) override; |
| std::vector<uint8_t> read(uint32_t offset, uint32_t requestedSize) override; |
| std::vector<uint8_t> readBlob(const std::string& blobId) const override; |
| bool write(uint32_t offset, const std::vector<uint8_t>& data) override; |
| bool commit() override; |
| bool close() override; |
| bool stat(blobs::BlobMeta* meta) override; |
| |
| /** |
| * Helper factory method to create a BinaryStore instance |
| * @param baseBlobId: base id for the created instance |
| * @param sysFile: system file object for storing binary |
| * @returns unique_ptr to constructed BinaryStore. Caller should take |
| * ownership of the instance. |
| */ |
| static std::unique_ptr<BinaryStoreInterface> createFromConfig( |
| const std::string& baseBlobId, std::unique_ptr<SysFile> file, |
| std::optional<uint32_t> maxSize = std::nullopt, |
| std::optional<std::string> aliasBlobBaseId = std::nullopt); |
| |
| /** |
| * Helper factory method to create a BinaryStore instance |
| * This function should be used with existing stores. It reads |
| * the baseBlobId name from the storage. |
| * @param sysFile: system file object for storing binary |
| * @param readOnly: if true, open the store in read only mode |
| * @returns unique_ptr to constructed BinaryStore. |
| */ |
| static std::unique_ptr<BinaryStoreInterface> |
| createFromFile(std::unique_ptr<SysFile> file, bool readOnly = true, |
| std::optional<uint32_t> maxSize = std::nullopt); |
| |
| private: |
| /* Load the serialized data from sysfile if commit state is dirty. |
| * Returns False if encountered error when loading */ |
| bool loadSerializedData( |
| std::optional<std::string> aliasBlobBaseId = std::nullopt); |
| |
| std::string baseBlobId_; |
| binaryblobproto::BinaryBlobBase blob_; |
| binaryblobproto::BinaryBlob* currentBlob_ = nullptr; |
| /* True if current blob is writable */ |
| bool writable_ = false; |
| /* True if the entire store (not just individual blobs) is read only */ |
| bool readOnly_ = false; |
| std::unique_ptr<SysFile> file_ = nullptr; |
| CommitState commitState_ = CommitState::Dirty; |
| std::optional<uint32_t> maxSize; |
| }; |
| |
| } // namespace binstore |