// This Source Code Form is subject to the terms of the Mozilla Public // License, version 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #pragma once #include #include #include #include #include #include #include #include #include #include #include namespace libsignal { template struct deleter { void operator() (T *ptr) { SIGNAL_UNREF(ptr); } }; template using object = std::unique_ptr>; template class type { private: T *_ptr; protected: typedef T* pointer_type; inline type(T *ptr) : _ptr(ptr) { } template>>> inline void call(Args&&... args) { int ret = func(*this, std::forward(args)...); if (ret != success) throw std::runtime_error( fmt::format("Signal Error: expected {}, was {}", success, ret)); } template>>> inline typename std::invoke_result::type call(Args&&... args) { return func(*this, std::forward(args)...); } public: inline explicit type() : _ptr(nullptr) { } template inline explicit type(Args&&... args) : type() { f_create(&_ptr, std::forward(args)...); } inline ~type() { if (_ptr) f_destroy(reinterpret_cast(_ptr)); _ptr = nullptr; } type(const type &other) = delete; /* no copy construction */ type(type &&other) = default; template inline void create(Args&&... args) { if (_ptr) f_destroy(reinterpret_cast(_ptr)); _ptr = nullptr; f_create(&_ptr, std::forward(args)...); } type& operator =(const type &other) = delete; /* no copy assignment */ type& operator =(type &&other) = default; inline operator bool() const { return _ptr; } inline T* operator *() { return _ptr; } inline operator T*() { return _ptr; } inline operator const T*() const { return _ptr; } }; typedef type context_type; class context : public context_type { public: using context_type::context_type; inline auto set_log_function(auto &&...args) { return call(args...); } inline auto set_crypto_provider(auto &&...args) { return call(args...); } inline auto set_locking_functions(auto &&...args) { return call(args...); } }; typedef type store_context_type; class store_context : public store_context_type { public: using store_context_type::store_context_type; inline auto set_identity_key_store(auto &&...args) { return call(args...); } inline auto set_pre_key_store(auto &&...args) { return call(args...); } inline auto set_signed_pre_key_store(auto &&...args) { return call(args...); } inline auto set_session_store(auto &&...args) { return call(args...); } inline auto set_sender_key_store(auto &&...args) { return call(args...); } }; typedef type public_key_type; class public_key : public public_key_type { public: using public_key_type::public_key_type; inline static public_key deserialize(auto &&...args) { pointer_type pointer; ec_public_key_deserialize(&pointer, args...); return public_key(pointer); } inline auto serialize(auto &&...args) { return call(args...); } friend class identity_key_pair; }; typedef type private_key_type; class private_key : public private_key_type { public: using private_key_type::private_key_type; inline static private_key deserialize(auto &&...args) { pointer_type pointer; ec_private_key_deserialize(&pointer, args...); return private_key(pointer); } inline auto serialize(auto &&...args) { return call(args...); } friend class identity_key_pair; }; typedef type identity_key_pair_type; class identity_key_pair : public identity_key_pair_type { public: using identity_key_pair_type::identity_key_pair_type; inline static identity_key_pair generate(auto &&...args) { pointer_type pointer; signal_protocol_key_helper_generate_identity_key_pair(&pointer, args...); return identity_key_pair(pointer); } inline public_key get_public(auto &&...args) { return call(args...); } inline private_key get_private(auto &&...args) { return call(args...); } }; typedef type pre_key_bundle_type; class pre_key_bundle : public pre_key_bundle_type { public: using pre_key_bundle_type::pre_key_bundle_type; }; typedef type session_builder_type; class session_builder : public session_builder_type { public: using session_builder_type::session_builder_type; inline auto process_pre_key_bundle(auto &&...args) { return call(args...); } }; }