QXmpp  Version: 1.6.0
OmemoLibWrappers.h
1 // SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im>
2 //
3 // SPDX-License-Identifier: LGPL-2.1-or-later
4 
5 #ifndef OMEMOLIBWRAPPERS_H
6 #define OMEMOLIBWRAPPERS_H
7 
8 #include <key_helper.h>
9 #include <session_builder.h>
10 #include <session_cipher.h>
11 #include <signal_protocol.h>
12 
13 #include <QByteArray>
14 
15 // Wraps various types of the OMEMO library.
16 template<typename T, void(destruct)(T *)>
17 class OmemoLibPtr
18 {
19  T *m_ptr = nullptr;
20 
21 public:
22  OmemoLibPtr(T *ptr = nullptr) : m_ptr(ptr) { }
23  OmemoLibPtr(const OmemoLibPtr &) = delete;
24  ~OmemoLibPtr()
25  {
26  if (m_ptr) {
27  destruct(m_ptr);
28  }
29  }
30  OmemoLibPtr &operator=(const OmemoLibPtr &) = delete;
31  OmemoLibPtr<T, destruct> &operator=(T *ptr)
32  {
33  reset(ptr);
34  return *this;
35  }
36  operator bool() const { return m_ptr != nullptr; }
37  T *operator->() const { return m_ptr; }
38  T *get() const { return m_ptr; }
39  T **ptrRef() { return &m_ptr; }
40  void reset(T *ptr)
41  {
42  if (m_ptr) {
43  destruct(m_ptr);
44  }
45  m_ptr = ptr;
46  }
47 };
48 
49 template<typename T>
50 void omemoLibUnrefHelper(T *ptr)
51 {
52  SIGNAL_UNREF(ptr);
53 }
54 
55 template<typename T>
56 using RefCountedPtr = OmemoLibPtr<T, omemoLibUnrefHelper<T>>;
57 
58 static QByteArray omemoLibBufferToByteArray(signal_buffer *buffer)
59 {
60  return QByteArray(reinterpret_cast<const char *>(signal_buffer_data(buffer)), signal_buffer_len(buffer));
61 }
62 
63 static signal_buffer *omemoLibBufferFromByteArray(const QByteArray &bytes)
64 {
65  return signal_buffer_create(reinterpret_cast<const unsigned char *>(bytes.constData()), bytes.size());
66 }
67 
68 template<void(destruct)(signal_buffer *)>
69 class BufferPtrBase : public OmemoLibPtr<signal_buffer, destruct>
70 {
71 public:
72  BufferPtrBase(signal_buffer *ptr)
73  : OmemoLibPtr<signal_buffer, destruct>(ptr)
74  {
75  }
76 
77  QByteArray toByteArray() const
78  {
79  return omemoLibBufferToByteArray(this->get());
80  }
81 };
82 
83 class BufferSecurePtr : public BufferPtrBase<signal_buffer_bzero_free>
84 {
85 public:
86  BufferSecurePtr() : BufferPtrBase<signal_buffer_bzero_free>(nullptr) { }
87  BufferSecurePtr(signal_buffer *ptr)
88  : BufferPtrBase<signal_buffer_bzero_free>(ptr)
89  {
90  }
91 
92  static BufferSecurePtr fromByteArray(const QByteArray &bytes)
93  {
94  return { omemoLibBufferFromByteArray(bytes) };
95  }
96 };
97 
98 class BufferPtr : public BufferPtrBase<signal_buffer_free>
99 {
100 public:
101  BufferPtr() : BufferPtrBase<signal_buffer_free>(nullptr) { }
102  BufferPtr(signal_buffer *ptr)
103  : BufferPtrBase<signal_buffer_free>(ptr)
104  {
105  }
106 
107  static BufferPtr fromByteArray(const QByteArray &bytes)
108  {
109  return { omemoLibBufferFromByteArray(bytes) };
110  }
111 };
112 
113 using KeyListNodePtr = OmemoLibPtr<signal_protocol_key_helper_pre_key_list_node, signal_protocol_key_helper_key_list_free>;
114 using SessionCipherPtr = OmemoLibPtr<session_cipher, session_cipher_free>;
115 using SessionBuilderPtr = OmemoLibPtr<session_builder, session_builder_free>;
116 using OmemoContextPtr = OmemoLibPtr<signal_context, signal_context_destroy>;
117 using StoreContextPtr = OmemoLibPtr<signal_protocol_store_context, signal_protocol_store_context_destroy>;
118 
119 #endif // OMEMOLIBWRAPPERS_H