diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2019-10-26 22:19:56 +0200 | 
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2019-12-10 21:29:28 +0100 | 
| commit | 361891f25ca735fd85db64a14823cc55b8a0619a (patch) | |
| tree | d45734fbc123d8dcb26128b314eb4453ecdd154e /include | |
| parent | 1a1b36dea942cd7b18067f3f1220c9ab4f9b4448 (diff) | |
Basic object encoding and storage
Diffstat (limited to 'include')
| -rw-r--r-- | include/erebos/storage.h | 172 | 
1 files changed, 172 insertions, 0 deletions
| 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 <array> +#include <filesystem> +#include <memory> +#include <optional> +#include <string> +#include <variant> +#include <vector> + +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<Storage> open(std::filesystem::path path); +	std::optional<Ref> ref(const Digest &) const; +	std::optional<Object> load(const Digest &) const; +	Ref store(const Object &) const; + +private: +	friend class Ref; +	struct Priv; +	const std::shared_ptr<const Priv> p; +	Storage(const std::shared_ptr<const Priv> 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<uint8_t, size> 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<uint8_t, size> value; +}; + +class Ref +{ +public: +	Ref(const Ref &) = default; +	Ref & operator=(const Ref &) = delete; + +	static std::optional<Ref> 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<const Priv> p; +	Ref(const std::shared_ptr<const Priv> p): p(p) {} +}; + +class Record +{ +public: +	class Item { +	public: +		typedef std::variant< +			int, +			std::string, +			std::vector<uint8_t>, +			Ref> Variant; + +		Item(const std::string & name, Variant value): +			name(name), value(value) {} +		Item(const Item &) = default; +		Item & operator=(const Item &) = delete; + +		std::optional<int> asInteger() const; +		std::optional<std::string> asText() const; +		std::optional<std::vector<uint8_t>> asBinary() const; +		std::optional<Ref> asRef() const; + +	private: +		friend class Record; +		std::string name; +		Variant value; +	}; + +private: +	Record(const std::shared_ptr<std::vector<Item>> & ptr): +		ptr(ptr) {} + +public: +	Record(const std::vector<Item> &); +	std::vector<uint8_t> encode() const; + +	const std::vector<Item> & items() const; +	std::optional<Item> item(const std::string & name) const; +	std::optional<Item> operator[](const std::string & name) const; +	std::vector<Item> items(const std::string & name) const; + +private: +	friend class Object; +	std::vector<uint8_t> encodeInner() const; +	static Record decode(Storage, +			std::vector<uint8_t>::const_iterator, +			std::vector<uint8_t>::const_iterator); + +	const std::shared_ptr<const std::vector<Item>> ptr; +}; + +class Blob +{ +public: +	Blob(const std::vector<uint8_t> &); + +	const std::vector<uint8_t> & data() const { return *ptr; } +	std::vector<uint8_t> encode() const; + +private: +	friend class Object; +	std::vector<uint8_t> encodeInner() const; +	static Blob decode(Storage, +			std::vector<uint8_t>::const_iterator, +			std::vector<uint8_t>::const_iterator); + +	Blob(std::shared_ptr<std::vector<uint8_t>> ptr): ptr(ptr) {} + +	const std::shared_ptr<const std::vector<uint8_t>> 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<Object> decode(Storage, const std::vector<uint8_t> &); +	std::vector<uint8_t> encode() const; + +	std::optional<Record> asRecord() const; +	std::optional<Blob> asBlob() const; + +private: +	friend class Record; +	friend class Blob; + +	Variants content; +}; + +} |