QXmpp  Version: 1.15.1
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()
40  {
41  reset(nullptr);
42  return &m_ptr;
43  }
44  void reset(T *ptr)
45  {
46  if (m_ptr) {
47  destruct(m_ptr);
48  }
49  m_ptr = ptr;
50  }
51 };
52 
53 template<typename T>
54 void omemoLibUnrefHelper(T *ptr)
55 {
56  SIGNAL_UNREF(ptr);
57 }
58 
59 template<typename T>
60 using RefCountedPtr = OmemoLibPtr<T, omemoLibUnrefHelper<T>>;
61 
62 static QByteArray omemoLibBufferToByteArray(signal_buffer *buffer)
63 {
64  return QByteArray(reinterpret_cast<const char *>(signal_buffer_data(buffer)), signal_buffer_len(buffer));
65 }
66 
67 static signal_buffer *omemoLibBufferFromByteArray(const QByteArray &bytes)
68 {
69  return signal_buffer_create(reinterpret_cast<const unsigned char *>(bytes.constData()), bytes.size());
70 }
71 
72 template<void(destruct)(signal_buffer *)>
73 class BufferPtrBase : public OmemoLibPtr<signal_buffer, destruct>
74 {
75 public:
76  BufferPtrBase(signal_buffer *ptr)
77  : OmemoLibPtr<signal_buffer, destruct>(ptr)
78  {
79  }
80 
81  QByteArray toByteArray() const
82  {
83  return omemoLibBufferToByteArray(this->get());
84  }
85 };
86 
87 class BufferSecurePtr : public BufferPtrBase<signal_buffer_bzero_free>
88 {
89 public:
90  BufferSecurePtr() : BufferPtrBase<signal_buffer_bzero_free>(nullptr) { }
91  BufferSecurePtr(signal_buffer *ptr)
92  : BufferPtrBase<signal_buffer_bzero_free>(ptr)
93  {
94  }
95 
96  static BufferSecurePtr fromByteArray(const QByteArray &bytes)
97  {
98  return { omemoLibBufferFromByteArray(bytes) };
99  }
100 };
101 
102 class BufferPtr : public BufferPtrBase<signal_buffer_free>
103 {
104 public:
105  BufferPtr() : BufferPtrBase<signal_buffer_free>(nullptr) { }
106  BufferPtr(signal_buffer *ptr)
107  : BufferPtrBase<signal_buffer_free>(ptr)
108  {
109  }
110 
111  static BufferPtr fromByteArray(const QByteArray &bytes)
112  {
113  return { omemoLibBufferFromByteArray(bytes) };
114  }
115 };
116 
117 using KeyListNodePtr = OmemoLibPtr<signal_protocol_key_helper_pre_key_list_node, signal_protocol_key_helper_key_list_free>;
118 using SessionCipherPtr = OmemoLibPtr<session_cipher, session_cipher_free>;
119 using SessionBuilderPtr = OmemoLibPtr<session_builder, session_builder_free>;
120 using OmemoContextPtr = OmemoLibPtr<signal_context, signal_context_destroy>;
121 using StoreContextPtr = OmemoLibPtr<signal_protocol_store_context, signal_protocol_store_context_destroy>;
122 
123 #endif // OMEMOLIBWRAPPERS_H