98 OPENDHT_PUBLIC
static bool DEFAULT_STORE_POLICY(InfoHash,
const std::shared_ptr<Value>& v,
const InfoHash&,
const SockAddr&);
99 static inline bool DEFAULT_EDIT_POLICY(InfoHash,
const std::shared_ptr<Value>&, std::shared_ptr<Value>&,
const InfoHash&,
const SockAddr&) {
105 ValueType (Id
id, std::string name, duration e = DEFAULT_VALUE_EXPIRATION)
106 : id(
id), name(name), expiration(e) {}
109 : id(
id), name(name), expiration(e), storePolicy(sp), editPolicy(ep) {}
111 virtual ~ValueType() {}
113 bool operator==(
const ValueType& o) {
118 OPENDHT_PUBLIC
static const ValueType USER_DATA;
123 duration expiration {DEFAULT_VALUE_EXPIRATION};
150struct OPENDHT_PUBLIC Value
152 enum class Field :
int {
164 static const constexpr Id INVALID_ID {0};
166 class Filter :
public std::function<bool(const Value&)> {
170 template<
typename Functor>
171 Filter(Functor f) : std::function<bool(
const Value&)>::function(f) {}
173 inline Filter chain(Filter&& f2) {
175 return chain(std::move(f1), std::move(f2));
177 inline Filter chainOr(Filter&& f2) {
179 return chainOr(std::move(f1), std::move(f2));
181 static inline Filter chain(Filter&& f1, Filter&& f2) {
182 if (not f1)
return std::move(f2);
183 if (not f2)
return std::move(f1);
184 return [f1 = std::move(f1), f2 = std::move(f2)](
const Value& v) {
185 return f1(v) and f2(v);
188 static inline Filter chain(
const Filter& f1,
const Filter& f2) {
189 if (not f1)
return f2;
190 if (not f2)
return f1;
191 return [f1,f2](
const Value& v) {
192 return f1(v) and f2(v);
195 static inline Filter chainAll(std::vector<Filter>&& set) {
196 if (set.empty())
return {};
197 return [set = std::move(set)](
const Value& v) {
198 for (
const auto& f : set)
204 static inline Filter chain(std::initializer_list<Filter> l) {
205 return chainAll(std::vector<Filter>(l.begin(), l.end()));
207 static inline Filter chainOr(Filter&& f1, Filter&& f2) {
208 if (not f1 or not f2)
return {};
209 return [f1=std::move(f1),f2=std::move(f2)](
const Value& v) {
210 return f1(v) or f2(v);
213 static inline Filter notFilter(Filter&& f) {
214 if (not f)
return [](
const Value&) {
return false; };
215 return [f = std::move(f)](
const Value& v) {
return not f(v); };
217 std::vector<Sp<Value>> filter(
const std::vector<Sp<Value>>& values) {
220 std::vector<Sp<Value>> ret;
221 for (
const auto& v : values)
230 static inline Filter AllFilter() {
234 static inline Filter TypeFilter(
const ValueType& t) {
235 return [tid = t.id](
const Value& v) {
236 return v.type == tid;
239 static inline Filter TypeFilter(
const ValueType::Id& tid) {
240 return [tid](
const Value& v) {
241 return v.type == tid;
245 static inline Filter IdFilter(
const Id
id) {
246 return [id](
const Value& v) {
251 static inline Filter RecipientFilter(
const InfoHash& r) {
252 return [r](
const Value& v) {
253 return v.recipient == r;
257 static inline Filter OwnerFilter(
const crypto::PublicKey& pk) {
258 return OwnerFilter(pk.getId());
261 static inline Filter OwnerFilter(
const InfoHash& pkh) {
262 return [pkh](
const Value& v) {
263 return v.owner and v.owner->getId() == pkh;
267 static inline Filter SeqNumFilter(uint16_t seq_no) {
268 return [seq_no](
const Value& v) {
269 return v.seq == seq_no;
273 static inline Filter UserTypeFilter(std::string ut) {
274 return [ut = std::move(ut)](
const Value& v) {
275 return v.user_type == ut;
279 class SerializableBase
282 SerializableBase() {}
283 virtual ~SerializableBase() {};
284 virtual const ValueType& getType()
const = 0;
285 virtual void unpackValue(
const Value& v) = 0;
286 virtual Value packValue()
const = 0;
289 template <
typename Derived,
typename Base=SerializableBase>
295 virtual const ValueType& getType()
const {
296 return Derived::TYPE;
299 virtual void unpackValue(
const Value& v) {
300 auto msg = msgpack::unpack((
const char*)v.data.data(), v.data.size());
301 msg.get().convert(*
static_cast<Derived*
>(
this));
304 virtual Value packValue()
const {
305 return Value {getType(),
static_cast<const Derived&
>(*this)};
309 template <
typename T,
310 typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>
::type* =
nullptr>
311 static Value pack(
const T& obj)
313 return obj.packValue();
316 template <
typename T,
317 typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
318 static Value pack(
const T& obj)
320 return {ValueType::USER_DATA.id, packMsg<T>(obj)};
323 template <
typename T,
324 typename std::enable_if<std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
325 static T unpack(
const Value& v)
332 template <
typename T,
333 typename std::enable_if<!std::is_base_of<SerializableBase, T>::value, T>::type* =
nullptr>
334 static T unpack(
const Value& v)
336 return unpackMsg<T>(v.data);
339 template <
typename T>
342 return unpack<T>(*
this);
345 inline bool isEncrypted()
const {
346 return not cypher.empty();
348 inline bool isSigned()
const {
349 return owner and not signature.empty();
367 inline std::shared_ptr<crypto::PublicKey> getOwner()
const {
378 Value (Id
id) : id(id) {}
381 Value(ValueType::Id t,
const Blob& data, Id
id = INVALID_ID)
382 : id(id),
type(t), data(data) {}
383 Value(ValueType::Id t,
Blob&& data, Id
id = INVALID_ID)
384 : id(id), type(t), data(std::move(data)) {}
385 Value(ValueType::Id t,
const uint8_t* dat_ptr,
size_t dat_len, Id
id = INVALID_ID)
386 : id(id), type(t), data(dat_ptr, dat_ptr+dat_len) {}
388#ifdef OPENDHT_JSONCPP
393 Value(
const Json::Value& json);
396 template <
typename Type>
397 Value(ValueType::Id t,
const Type& d, Id
id = INVALID_ID)
398 : id(id), type(t), data(packMsg(d)) {}
400 template <
typename Type>
401 Value(
const ValueType& t,
const Type& d, Id
id = INVALID_ID)
402 : id(id), type(t.id), data(packMsg(d)) {}
406 Value(
Blob&& userdata) : data(std::move(userdata)) {}
407 Value(
const uint8_t* dat_ptr,
size_t dat_len) : data(dat_ptr, dat_ptr+dat_len) {}
409 Value(Value&& o) noexcept
410 : id(o.id), owner(std::move(o.owner)), recipient(o.recipient),
411 type(o.type), data(std::move(o.data)), user_type(std::move(o.user_type)), seq(o.seq)
412 , signature(std::move(o.signature)), cypher(std::move(o.cypher))
413 , priority(o.priority) {}
415 template <
typename Type>
416 Value(
const Type& vs)
417 : Value(pack<Type>(vs)) {}
438 inline bool operator== (
const Value& o)
const {
439 return id == o.id and contentEquals(o);
441 inline bool operator!= (
const Value& o)
const {
442 return !(*
this == o);
445 inline void setRecipient(
const InfoHash& r) {
449 inline void setCypher(Blob&& c) {
450 cypher = std::move(c);
457 msgpack::sbuffer buffer;
458 msgpack::packer<msgpack::sbuffer> pk(&buffer);
459 msgpack_pack_to_sign(pk);
460 return {buffer.data(), buffer.data()+buffer.size()};
467 msgpack::sbuffer buffer;
468 msgpack::packer<msgpack::sbuffer> pk(&buffer);
469 msgpack_pack_to_encrypt(pk);
470 return {buffer.data(), buffer.data()+buffer.size()};
474 OPENDHT_PUBLIC
friend std::ostream& operator<< (std::ostream& s,
const Value& v);
476 inline std::string toString()
const {
477 std::ostringstream ss;
482#ifdef OPENDHT_JSONCPP
491 Json::Value toJson()
const;
497 template <
typename Packer>
498 void msgpack_pack_to_sign(Packer& pk)
const
503 pk.pack(VALUE_KEY_SEQ); pk.pack(
seq);
504 pk.pack(VALUE_KEY_OWNER);
owner->msgpack_pack(pk);
506 pk.pack(VALUE_KEY_TO); pk.pack(
recipient);
509 pk.pack(VALUE_KEY_TYPE); pk.pack(type);
510 pk.pack(VALUE_KEY_DATA); pk.pack_bin(data.size());
511 pk.pack_bin_body((
const char*)data.data(), data.size());
512 if (not user_type.empty()) {
513 pk.pack(VALUE_KEY_USERTYPE); pk.pack(user_type);
517 template <
typename Packer>
518 void msgpack_pack_to_encrypt(Packer& pk)
const
521 pk.pack_bin(cypher.size());
522 pk.pack_bin_body((
const char*)cypher.data(), cypher.size());
524 pk.pack_map(isSigned() ? 2 : 1);
525 pk.pack(VALUE_KEY_BODY); msgpack_pack_to_sign(pk);
527 pk.pack(VALUE_KEY_SIGNATURE); pk.pack_bin(signature.size());
528 pk.pack_bin_body((
const char*)signature.data(), signature.size());
533 template <
typename Packer>
534 void msgpack_pack(Packer& pk)
const
536 pk.pack_map(2 + (priority?1:0));
537 pk.pack(VALUE_KEY_ID); pk.pack(
id);
538 pk.pack(VALUE_KEY_DAT); msgpack_pack_to_encrypt(pk);
540 pk.pack(VALUE_KEY_PRIO); pk.pack(priority);
544 template <
typename Packer>
545 void msgpack_pack_fields(
const std::set<Value::Field>& fields, Packer& pk)
const
547 for (
const auto& field : fields)
549 case Value::Field::Id:
550 pk.pack(
static_cast<uint64_t
>(
id));
552 case Value::Field::ValueType:
553 pk.pack(
static_cast<uint64_t
>(type));
555 case Value::Field::OwnerPk:
557 owner->msgpack_pack(pk);
559 InfoHash().msgpack_pack(pk);
561 case Value::Field::SeqNum:
562 pk.pack(
static_cast<uint64_t
>(seq));
564 case Value::Field::UserType:
572 void msgpack_unpack(
const msgpack::object& o);
573 void msgpack_unpack_body(
const msgpack::object& o);
574 Blob getPacked()
const {
575 msgpack::sbuffer buffer;
576 msgpack::packer<msgpack::sbuffer> pk(&buffer);
578 return {buffer.data(), buffer.data()+buffer.size()};
581 void msgpack_unpack_fields(
const std::set<Value::Field>& fields,
const msgpack::object& o,
unsigned offset);
588 std::shared_ptr<crypto::PublicKey>
owner {};
600 ValueType::Id
type {ValueType::USER_DATA.id};
630 inline bool isSignatureChecked()
const {
631 return signatureChecked;
633 inline bool isDecrypted()
const {
636 bool checkSignature();
637 Sp<Value> decrypt(
const crypto::PrivateKey& key);
641 bool signatureChecked {
false};
642 bool signatureValid {
false};
643 bool decrypted {
false};
644 Sp<Value> decryptedValue {};
656struct OPENDHT_PUBLIC FieldValue
659 FieldValue(Value::Field f, uint64_t int_value) : field(f), intValue(int_value) {}
660 FieldValue(Value::Field f, InfoHash hash_value) : field(f), hashValue(hash_value) {}
661 FieldValue(Value::Field f,
Blob blob_value) : field(f), blobValue(std::move(blob_value)) {}
663 bool operator==(
const FieldValue& fd)
const;
666 Value::Field getField()
const {
return field; }
667 uint64_t getInt()
const {
return intValue; }
668 InfoHash getHash()
const {
return hashValue; }
669 Blob getBlob()
const {
return blobValue; }
671 template <
typename Packer>
672 void msgpack_pack(Packer& p)
const {
674 p.pack(
"f"sv); p.pack(
static_cast<uint8_t
>(field));
678 case Value::Field::Id:
679 case Value::Field::ValueType:
682 case Value::Field::OwnerPk:
685 case Value::Field::UserType:
686 p.pack_bin(blobValue.size());
687 p.pack_bin_body((
const char*)blobValue.data(), blobValue.size());
690 throw msgpack::type_error();
694 void msgpack_unpack(
const msgpack::object& msg) {
698 if (
auto f = findMapValue(msg,
"f"sv))
699 field = (Value::Field)f->as<
unsigned>();
701 throw msgpack::type_error();
703 auto v = findMapValue(msg,
"v"sv);
705 throw msgpack::type_error();
708 case Value::Field::Id:
709 case Value::Field::ValueType:
710 intValue = v->as<
decltype(intValue)>();
712 case Value::Field::OwnerPk:
713 hashValue = v->as<
decltype(hashValue)>();
715 case Value::Field::UserType:
719 throw msgpack::type_error();
726 Value::Field field {Value::Field::None};
728 uint64_t intValue {};
729 InfoHash hashValue {};