diff options
| -rw-r--r-- | include/erebos/storage.h | 4 | ||||
| -rw-r--r-- | src/network/protocol.cpp | 2 | ||||
| -rw-r--r-- | src/storage.cpp | 29 | 
3 files changed, 30 insertions, 5 deletions
| diff --git a/include/erebos/storage.h b/include/erebos/storage.h index 3feb22b..48bedd7 100644 --- a/include/erebos/storage.h +++ b/include/erebos/storage.h @@ -174,6 +174,7 @@ public:  	PartialRef & operator=(PartialRef &&) = default;  	static PartialRef create(const PartialStorage &, const Digest &); +	static PartialRef zcreate(const PartialStorage &);  	const Digest & digest() const; @@ -234,6 +235,7 @@ private:  		ptr(ptr) {}  public: +	RecordT(): RecordT(std::vector<Item> {}) {}  	RecordT(const std::vector<Item> &);  	RecordT(std::vector<Item> &&);  	std::vector<uint8_t> encode() const; @@ -420,6 +422,8 @@ public:  	std::vector<uint8_t> encode() const;  	static ObjectT<S> load(const typename S::Ref &); +	operator bool() const; +  	std::optional<RecordT<S>> asRecord() const;  	std::optional<Blob> asBlob() const; diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp index 8e0de61..02c3dae 100644 --- a/src/network/protocol.cpp +++ b/src/network/protocol.cpp @@ -134,7 +134,7 @@ NetworkProtocol::Connection NetworkProtocol::connect(sockaddr_in6 addr)  		connections.push_back(conn.get());  		vector<Header::Item> header { -			Header::Initiation { Digest(array<uint8_t, Digest::size> {}) }, +			Header::Initiation { Digest::of(Object(Record())) },  			Header::AnnounceSelf { self->ref()->digest() },  			Header::Version { defaultVersion },  		}; diff --git a/src/storage.cpp b/src/storage.cpp index 366fe71..19f35a9 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -746,7 +746,11 @@ optional<PartialObject> PartialStorage::loadObject(const Digest & digest) const  }  PartialRef PartialStorage::storeObject(const PartialObject & obj) const -{ return ref(p->storeBytes(obj.encode())); } +{ +	if (not obj) +		return PartialRef::zcreate(*this); +	return ref(p->storeBytes(obj.encode())); +}  PartialRef PartialStorage::storeObject(const PartialRecord & val) const  { return storeObject(PartialObject(val)); } @@ -775,6 +779,8 @@ Ref Storage::storeObject(const Blob & val) const  template<class S>  optional<Digest> Storage::Priv::copy(const typename S::Ref & pref, vector<Digest> * missing) const  { +	if (pref.digest().isZero()) +		return pref.digest();  	if (backend->contains(pref.digest()))  		return pref.digest();  	if (pref) @@ -787,6 +793,9 @@ optional<Digest> Storage::Priv::copy(const typename S::Ref & pref, vector<Digest  template<class S>  optional<Digest> Storage::Priv::copy(const ObjectT<S> & pobj, vector<Digest> * missing) const  { +	if (not pobj) +		return Digest(array<uint8_t, Digest::size> {}); +  	bool fail = false;  	if (auto rec = pobj.asRecord())  		for (const auto & r : rec->items().asRef()) @@ -948,6 +957,11 @@ PartialRef PartialRef::create(const PartialStorage & st, const Digest & digest)  	return PartialRef(shared_ptr<Priv>(p));  } +PartialRef PartialRef::zcreate(const PartialStorage & st) +{ +	return create(st, Digest(array<uint8_t, Digest::size> {})); +} +  const Digest & PartialRef::digest() const  {  	return p->digest; @@ -1421,9 +1435,6 @@ vector<uint8_t> RecordT<S>::encodeInner() const  	vector<uint8_t> res;  	auto inserter = std::back_inserter(res);  	for (const auto & item : *ptr) { -		copy(item.name.begin(), item.name.end(), inserter); -		inserter = ':'; -  		string type;  		string value; @@ -1451,6 +1462,8 @@ vector<uint8_t> RecordT<S>::encodeInner() const  			value = string(*x);  		} else if (auto x = item.asRef()) {  			type = "r"; +			if (x->digest().isZero()) +				continue;  			value = string(x->digest());  		} else if (auto x = item.asUnknown()) {  			type = x->type; @@ -1459,6 +1472,8 @@ vector<uint8_t> RecordT<S>::encodeInner() const  			throw runtime_error("unhandeled record item type");  		} +		copy(item.name.begin(), item.name.end(), inserter); +		inserter = ':';  		copy(type.begin(), type.end(), inserter);  		inserter = ' '; @@ -1599,6 +1614,12 @@ ObjectT<S> ObjectT<S>::load(const typename S::Ref & ref)  }  template<class S> +ObjectT<S>::operator bool() const +{ +	return not holds_alternative<monostate>(content); +} + +template<class S>  optional<RecordT<S>> ObjectT<S>::asRecord() const  {  	if (holds_alternative<RecordT<S>>(content)) |