From 361891f25ca735fd85db64a14823cc55b8a0619a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Sat, 26 Oct 2019 22:19:56 +0200 Subject: Basic object encoding and storage --- include/erebos/storage.h | 172 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 include/erebos/storage.h (limited to 'include/erebos') diff --git a/include/erebos/storage.h b/include/erebos/storage.h new file mode 100644 index 0000000..ae899f5 --- /dev/null +++ b/include/erebos/storage.h @@ -0,0 +1,172 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace erebos { + +class Storage; +class Digest; +class Ref; +class Object; + +class Storage +{ +public: + Storage(const Storage &) = default; + Storage & operator=(const Storage &) = delete; + + static std::optional open(std::filesystem::path path); + std::optional ref(const Digest &) const; + std::optional load(const Digest &) const; + Ref store(const Object &) const; + +private: + friend class Ref; + struct Priv; + const std::shared_ptr p; + Storage(const std::shared_ptr p): p(p) {} +}; + +class Digest +{ +public: + static constexpr size_t size = 32; + + Digest(const Digest &) = default; + Digest & operator=(const Digest &) = delete; + + explicit Digest(std::array value): value(value) {} + explicit Digest(const std::string &); + explicit operator std::string() const; + + bool operator==(const Digest & other) const { return value == other.value; } + bool operator!=(const Digest & other) const { return value != other.value; } + bool operator<(const Digest & other) const { return value < other.value; } + bool operator<=(const Digest & other) const { return value <= other.value; } + bool operator>(const Digest & other) const { return value > other.value; } + bool operator>=(const Digest & other) const { return value >= other.value; } + +private: + std::array value; +}; + +class Ref +{ +public: + Ref(const Ref &) = default; + Ref & operator=(const Ref &) = delete; + + static std::optional create(Storage, const Digest &); + + const Digest & digest() const; + const Object & operator*() const; + const Object * operator->() const; + +private: + friend class Storage; + struct Priv; + const std::shared_ptr p; + Ref(const std::shared_ptr p): p(p) {} +}; + +class Record +{ +public: + class Item { + public: + typedef std::variant< + int, + std::string, + std::vector, + Ref> Variant; + + Item(const std::string & name, Variant value): + name(name), value(value) {} + Item(const Item &) = default; + Item & operator=(const Item &) = delete; + + std::optional asInteger() const; + std::optional asText() const; + std::optional> asBinary() const; + std::optional asRef() const; + + private: + friend class Record; + std::string name; + Variant value; + }; + +private: + Record(const std::shared_ptr> & ptr): + ptr(ptr) {} + +public: + Record(const std::vector &); + std::vector encode() const; + + const std::vector & items() const; + std::optional item(const std::string & name) const; + std::optional operator[](const std::string & name) const; + std::vector items(const std::string & name) const; + +private: + friend class Object; + std::vector encodeInner() const; + static Record decode(Storage, + std::vector::const_iterator, + std::vector::const_iterator); + + const std::shared_ptr> ptr; +}; + +class Blob +{ +public: + Blob(const std::vector &); + + const std::vector & data() const { return *ptr; } + std::vector encode() const; + +private: + friend class Object; + std::vector encodeInner() const; + static Blob decode(Storage, + std::vector::const_iterator, + std::vector::const_iterator); + + Blob(std::shared_ptr> ptr): ptr(ptr) {} + + const std::shared_ptr> ptr; +}; + +class Object +{ +public: + typedef std::variant< + Record, + Blob> Variants; + + Object(const Object &) = default; + Object(Variants content): content(content) {} + Object & operator=(const Object &) = delete; + + static std::optional decode(Storage, const std::vector &); + std::vector encode() const; + + std::optional asRecord() const; + std::optional asBlob() const; + +private: + friend class Record; + friend class Blob; + + Variants content; +}; + +} -- cgit v1.2.3