| #pragma once | 
 |  | 
 | #include <unistd.h> | 
 |  | 
 | #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 binstore | 
 | { | 
 |  | 
 | /** | 
 |  * @class BinaryStoreInterface is an abstraction for a storage location. | 
 |  *     Each instance would be uniquely identified by a baseId string. | 
 |  */ | 
 | class BinaryStoreInterface | 
 | { | 
 |   public: | 
 |     virtual ~BinaryStoreInterface() = default; | 
 |  | 
 |     /** | 
 |      * @returns baseId string of the storage. | 
 |      */ | 
 |     virtual std::string getBaseBlobId() const = 0; | 
 |  | 
 |     /** | 
 |      * @returns List of all open blob IDs, plus the base. | 
 |      */ | 
 |     virtual std::vector<std::string> getBlobIds() const = 0; | 
 |  | 
 |     /** | 
 |      * Opens a blob given its name. If there is no one, create one. | 
 |      * @param blobId: The blob id to operate on. | 
 |      * @param flags: Either read flag or r/w flag has to be specified. | 
 |      * @returns True if open/create successfully. | 
 |      */ | 
 |     virtual bool openOrCreateBlob(const std::string& blobId, | 
 |                                   uint16_t flags) = 0; | 
 |  | 
 |     /** | 
 |      * Deletes a blob given its name. If there is no one, | 
 |      * @param blobId: The blob id to operate on. | 
 |      * @returns True if deleted. | 
 |      */ | 
 |     virtual bool deleteBlob(const std::string& blobId) = 0; | 
 |  | 
 |     /** | 
 |      * Reads data from the currently opened blob. | 
 |      * @param offset: offset into the blob to read | 
 |      * @param requestedSize: how many bytes to read | 
 |      * @returns Bytes able to read. Returns empty if nothing can be read or | 
 |      *          if there is no open blob. | 
 |      */ | 
 |     virtual std::vector<uint8_t> read(uint32_t offset, | 
 |                                       uint32_t requestedSize) = 0; | 
 |  | 
 |     /** | 
 |      * Writes data to the currently openend blob. | 
 |      * @param offset: offset into the blob to write | 
 |      * @param data: bytes to write | 
 |      * @returns True if able to write the entire data successfully | 
 |      */ | 
 |     virtual bool write(uint32_t offset, const std::vector<uint8_t>& data) = 0; | 
 |  | 
 |     /** | 
 |      * TODO | 
 |      */ | 
 |     virtual bool commit() = 0; | 
 |  | 
 |     /** | 
 |      * TODO | 
 |      */ | 
 |     virtual bool close() = 0; | 
 |  | 
 |     /** | 
 |      * TODO | 
 |      */ | 
 |     virtual bool stat() = 0; | 
 | }; | 
 |  | 
 | // TODO: move to protobuf definition | 
 | struct BinaryBlobSingle | 
 | { | 
 |     std::string id; | 
 |     std::vector<uint8_t> data; | 
 | }; | 
 |  | 
 | struct BinaryBlob | 
 | { | 
 |     std::string baseBlobId; | 
 |     std::vector<BinaryBlobSingle> blobs; | 
 | }; | 
 |  | 
 | /** | 
 |  * @class BinaryStore instantiates a concrete implementation of | 
 |  *     BinaryStoreInterface. The dependency on file is injected through its | 
 |  *     constructor. | 
 |  */ | 
 | class BinaryStore : public BinaryStoreInterface | 
 | { | 
 |   public: | 
 |     BinaryStore(const std::string& baseBlobId, int fd, uint32_t offset, | 
 |                 uint32_t maxSize) : | 
 |         baseBlobId_(baseBlobId), | 
 |         fd_(fd), offset_(offset), maxSize_(maxSize) | 
 |     { | 
 |     } | 
 |  | 
 |     BinaryStore() = delete; | 
 |     ~BinaryStore() = default; | 
 |     BinaryStore(const BinaryStore&) = delete; | 
 |     BinaryStore& operator=(const BinaryStore&) = delete; | 
 |     BinaryStore(BinaryStore&&) = default; | 
 |     BinaryStore& operator=(BinaryStore&&) = default; | 
 |  | 
 |     std::string getBaseBlobId() const 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; | 
 |     bool write(uint32_t offset, const std::vector<uint8_t>& data) override; | 
 |     bool commit() override; | 
 |     bool close() override; | 
 |     bool stat() override; | 
 |  | 
 |     /** | 
 |      * Helper factory method to create a BinaryStore instance | 
 |      * @param baseBlobId: base id for the created instance | 
 |      * @param sysfilePath: path to the storage location | 
 |      * @param offset: offset into the file for serializing the final blob | 
 |      * @param maxSize: max size in bytes that this BinaryStore can expand to. | 
 |      *     Writing data more than allowed size will return failure. | 
 |      * @returns unique_ptr to constructed BinaryStore. Caller should take | 
 |      *     ownership of the instance. | 
 |      */ | 
 |     static std::unique_ptr<BinaryStoreInterface> | 
 |         createFromConfig(const std::string& baseBlobId, | 
 |                          const std::string& sysfilePath, uint32_t offset, | 
 |                          uint32_t maxSize); | 
 |  | 
 |   private: | 
 |     std::string baseBlobId_; | 
 |     int fd_; | 
 |     uint32_t offset_; | 
 |     uint32_t maxSize_; | 
 |     BinaryBlob blob_; | 
 | }; | 
 |  | 
 | } // namespace binstore |