1
0
forked from blue/squawk

BUILD FAILS! some ideas of storage and cache

This commit is contained in:
Blue 2022-09-03 14:39:42 +03:00
parent 87973b3b67
commit 820dc845ea
Signed by untrusted user: blue
GPG Key ID: 9B203B252A63EE38
10 changed files with 198 additions and 89 deletions

View File

@ -35,7 +35,12 @@ option(WITH_OMEMO "Build OMEMO support module" ON)
# Dependencies
## Qt
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets DBus Gui Xml Network Core)
if (NOT DEFINED QT_VERSION_MAJOR)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets DBus Gui Xml Network Core)
else ()
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets DBus Gui Xml Network Core)
endif()
find_package(Boost COMPONENTS)
target_include_directories(squawk PRIVATE ${Boost_INCLUDE_DIRS})
@ -51,21 +56,15 @@ target_include_directories(squawk PRIVATE ${Qt${QT_VERSION_MAJOR}Core_INCLUDE_DI
if (WITH_OMEMO)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_check_modules(OMEMO libomemo)
pkg_check_modules(OMEMO libomemo-c)
if (OMEMO_FOUND)
pkg_check_modules(SIGNAL libsignal-protocol-c)
if (SIGNAL_FOUND)
message("Building with support of OMEMO")
else ()
message("signal-protocol package wasn't found, trying to build without OMEMO support")
set(WITH_OMEMO OFF)
endif()
else ()
message("libomemo package wasn't found, trying to build without OMEMO support")
message("libomemo-c package wasn't found, trying to build without OMEMO support")
set(WITH_OMEMO OFF)
endif ()
else ()
message("PKG_CONFIG module wasn't found, can not check libomemo and libsignal-protocol support, trying to build without OMEMO support")
message("PKG_CONFIG module wasn't found, can not check libomemo-c support, trying to build without OMEMO support")
set(WITH_OMEMO OFF)
endif ()
endif ()
@ -129,16 +128,18 @@ endif()
if (NOT SYSTEM_QXMPP)
message("Building with bundled QXmpp")
target_include_directories(squawk PRIVATE ${CMAKE_SOURCE_DIR}/external/qxmpp/src/base)
target_include_directories(squawk PRIVATE ${CMAKE_SOURCE_DIR}/external/qxmpp/src/client)
if (WITH_OMEMO)
target_include_directories(squawk PRIVATE ${CMAKE_SOURCE_DIR}/external/qxmpp/src/omemo)
target_include_directories(squawk PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/external/qxmpp/src/omemo)
set(BUILD_OMEMO ON)
target_compile_definitions(squawk PRIVATE WITH_OMEMO)
else ()
set(BUILD_OMEMO OFF)
endif ()
add_subdirectory(external/qxmpp)
if (WITH_OMEMO)
target_include_directories(QXmppOmemo PRIVATE ${SIGNAL_INCLUDE_DIRS})
target_include_directories(QXmppOmemo PRIVATE ${OMEMO_INCLUDE_DIRS})
endif ()
target_link_libraries(squawk PRIVATE qxmpp)
else ()

View File

@ -304,12 +304,16 @@ void Core::Account::onPresenceReceived(const QXmppPresence& p_presence)
break;
case QXmppPresence::Subscribe:
qDebug("xmpp presence \"subscribe\" received, do not yet know what to do, skipping");
break;
case QXmppPresence::Subscribed:
qDebug("xmpp presence \"subscribed\" received, do not yet know what to do, skipping");
break;
case QXmppPresence::Unsubscribe:
qDebug("xmpp presence \"unsubscribe\" received, do not yet know what to do, skipping");
break;
case QXmppPresence::Unsubscribed:
qDebug("xmpp presence \"unsubscribed\" received, do not yet know what to do, skipping");
break;
case QXmppPresence::Probe:
qDebug("xmpp presence \"probe\" received, do not yet know what to do, skipping");
break;

View File

@ -47,7 +47,7 @@ public slots:
private:
std::map<QString, Shared::ClientInfo> requested;
Cache<Shared::ClientInfo> cache;
Cache<QString, Shared::ClientInfo> cache;
std::map<QString, Shared::ClientInfo> specific;
};

View File

@ -7,4 +7,6 @@ target_sources(squawk PRIVATE
vcardhandler.h
discoveryhandler.cpp
discoveryhandler.h
omemohandler.cpp
omemohandler.h
)

View File

@ -0,0 +1,17 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "omemohandler.h"

View File

@ -0,0 +1,57 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef CORE_OMEMOHANDLER_H
#define CORE_OMEMOHANDLER_H
#include <QXmppOmemoStorage.h>
#include <core/storage/cache.h>
namespace Core {
class OmemoHandler : public QXmppOmemoStorage
{
public:
OmemoHandler();
~OmemoHandler() override;
QFuture<OmemoData> allData() override;
QFuture<void> setOwnDevice(const std::optional<OwnDevice> &device) override;
QFuture<void> addSignedPreKeyPair(uint32_t keyId, const SignedPreKeyPair &keyPair) override;
QFuture<void> removeSignedPreKeyPair(uint32_t keyId) override;
QFuture<void> addPreKeyPairs(const QHash<uint32_t, QByteArray> &keyPairs) override;
QFuture<void> removePreKeyPair(uint32_t keyId) override;
QFuture<void> addDevice(const QString &jid, uint32_t deviceId, const Device &device) override;
QFuture<void> removeDevice(const QString &jid, uint32_t deviceId) override;
QFuture<void> removeDevices(const QString &jid) override;
QFuture<void> resetAll() override;
private:
std::optional<OwnDevice> ownDevice;
Cache<QString, QHash<uint32_t, Device>> devices;
Cache<uint32_t, QByteArray> preKeyPairs;
Cache<uint32_t, QXmppOmemoStorage::SignedPreKeyPair> signedPreKeyPairs;
};
}
#endif // CORE_OMEMOHANDLER_H

View File

@ -26,7 +26,7 @@
namespace Core {
template <class T>
template <class K, class V>
class Cache
{
public:
@ -36,16 +36,16 @@ public:
void open();
void close();
void addRecord(const QString& key, const T& value);
void changeRecord(const QString& key, const T& value);
void removeRecord(const QString& key);
T getRecord(const QString& key) const;
bool checkRecord(const QString& key) const;
void addRecord(const K& key, const V& value);
void changeRecord(const K& key, const V& value);
void removeRecord(const K& key);
V getRecord(const K& key) const;
bool checkRecord(const K& key) const;
private:
Core::Storage<T> storage;
std::map<QString, T>* cache;
std::set<QString>* abscent;
Core::Storage<K, V> storage;
std::map<K, V>* cache;
std::set<K>* abscent;
};
}

View File

@ -18,44 +18,44 @@
#define CORE_CACHE_HPP
#include "cache.h"
template <class T>
Core::Cache<T>::Cache(const QString& name):
template <class K, class V>
Core::Cache<K, V>::Cache(const QString& name):
storage(name),
cache(new std::map<QString, T> ()),
abscent(new std::set<QString> ()) {}
cache(new std::map<K, V> ()),
abscent(new std::set<K> ()) {}
template <class T>
Core::Cache<T>::~Cache() {
template <class K, class V>
Core::Cache<K, V>::~Cache() {
close();
delete cache;
delete abscent;
}
template <class T>
void Core::Cache<T>::open() {
template <class K, class V>
void Core::Cache<K, V>::open() {
storage.open();}
template <class T>
void Core::Cache<T>::close() {
template <class K, class V>
void Core::Cache<K, V>::close() {
storage.close();}
template <class T>
void Core::Cache<T>::addRecord(const QString& key, const T& value) {
template <class K, class V>
void Core::Cache<K, V>::addRecord(const K& key, const V& value) {
storage.addRecord(key, value);
cache->insert(std::make_pair(key, value));
abscent->erase(key);
}
template <class T>
T Core::Cache<T>::getRecord(const QString& key) const {
typename std::map<QString, T>::const_iterator itr = cache->find(key);
template <class K, class V>
V Core::Cache<K, V>::getRecord(const K& key) const {
typename std::map<K, V>::const_iterator itr = cache->find(key);
if (itr == cache->end()) {
if (abscent->count(key) > 0) {
throw Archive::NotFound(key, storage.getName().toStdString());
throw Archive::NotFound(std::to_string(key), storage.getName().toStdString());
}
try {
T value = storage.getRecord(key);
V value = storage.getRecord(key);
itr = cache->insert(std::make_pair(key, value)).first;
} catch (const Archive::NotFound& error) {
abscent->insert(key);
@ -66,9 +66,9 @@ T Core::Cache<T>::getRecord(const QString& key) const {
return itr->second;
}
template<class T>
bool Core::Cache<T>::checkRecord(const QString& key) const {
typename std::map<QString, T>::const_iterator itr = cache->find(key);
template<class K, class V>
bool Core::Cache<K, V>::checkRecord(const K& key) const {
typename std::map<K, V>::const_iterator itr = cache->find(key);
if (itr != cache->end())
return true;
@ -76,7 +76,7 @@ bool Core::Cache<T>::checkRecord(const QString& key) const {
return false;
try {
T value = storage.getRecord(key);
V value = storage.getRecord(key);
itr = cache->insert(std::make_pair(key, value)).first;
} catch (const Archive::NotFound& error) {
return false;
@ -85,15 +85,15 @@ bool Core::Cache<T>::checkRecord(const QString& key) const {
return true;
}
template<typename T>
void Core::Cache<T>::changeRecord(const QString& key, const T& value) {
template<class K, class V>
void Core::Cache<K, V>::changeRecord(const K& key, const V& value) {
storage.changeRecord(key, value); //there is a non straightforward behaviour: if there was no element at the sorage it will be added
cache->at(key) = value;
abscent->erase(key); //so... this line here is to make it coherent with the storage
}
template<typename T>
void Core::Cache<T>::removeRecord(const QString& key) {
template<class K, class V>
void Core::Cache<K, V>::removeRecord(const K& key) {
storage.removeRecord(key);
cache->erase(key);
abscent->insert(key);

View File

@ -29,7 +29,7 @@ namespace Core {
/**
* @todo write docs
*/
template <class T>
template <class K, class V>
class Storage
{
public:
@ -39,10 +39,10 @@ public:
void open();
void close();
void addRecord(const QString& key, const T& value);
void changeRecord(const QString& key, const T& value);
void removeRecord(const QString& key);
T getRecord(const QString& key) const;
void addRecord(const K& key, const V& value);
void changeRecord(const K& key, const V& value);
void removeRecord(const K& key);
V getRecord(const K& key) const;
QString getName() const;
@ -55,6 +55,16 @@ private:
}
MDB_val& operator << (MDB_val& data, QString& value);
MDB_val& operator >> (MDB_val& data, QString& value);
MDB_val& operator << (MDB_val& data, uint32_t& value);
MDB_val& operator >> (MDB_val& data, uint32_t& value);
namespace std {
std::string to_string(const QString& str);
}
#include "storage.hpp"
#endif // CORE_STORAGE_H

View File

@ -22,9 +22,10 @@
#include <QDir>
#include "storage.h"
#include <cstring>
template <class T>
Core::Storage<T>::Storage(const QString& p_name):
template <class K, class V>
Core::Storage<K, V>::Storage(const QString& p_name):
name(p_name),
opened(false),
environment(),
@ -32,14 +33,14 @@ Core::Storage<T>::Storage(const QString& p_name):
{
}
template <class T>
Core::Storage<T>::~Storage()
template <class K, class V>
Core::Storage<K, V>::~Storage()
{
close();
}
template <class T>
void Core::Storage<T>::open()
template <class K, class V>
void Core::Storage<K, V>::open()
{
if (!opened) {
mdb_env_create(&environment);
@ -66,8 +67,8 @@ void Core::Storage<T>::open()
}
}
template <class T>
void Core::Storage<T>::close()
template <class K, class V>
void Core::Storage<K, V>::close()
{
if (opened) {
mdb_dbi_close(environment, base);
@ -76,20 +77,19 @@ void Core::Storage<T>::close()
}
}
template <class T>
void Core::Storage<T>::addRecord(const QString& key, const T& value)
template <class K, class V>
void Core::Storage<K, V>::addRecord(const K& key, const V& value)
{
if (!opened) {
throw Archive::Closed("addRecord", name.toStdString());
}
QByteArray ba;
QDataStream ds(&ba, QIODevice::WriteOnly);
const std::string& id = key.toStdString();
ds << value;
MDB_val lmdbKey, lmdbData;
lmdbKey.mv_size = id.size();
lmdbKey.mv_data = (char*)id.c_str();
lmdbKey << key;
lmdbData.mv_size = ba.size();
lmdbData.mv_data = (uint8_t*)ba.data();
MDB_txn *txn;
@ -99,7 +99,7 @@ void Core::Storage<T>::addRecord(const QString& key, const T& value)
if (rc != 0) {
mdb_txn_abort(txn);
if (rc == MDB_KEYEXIST) {
throw Archive::Exist(name.toStdString(), id);
throw Archive::Exist(name.toStdString(), std::to_string(key));
} else {
throw Archive::Unknown(name.toStdString(), mdb_strerror(rc));
}
@ -108,8 +108,8 @@ void Core::Storage<T>::addRecord(const QString& key, const T& value)
}
}
template <class T>
void Core::Storage<T>::changeRecord(const QString& key, const T& value)
template <class K, class V>
void Core::Storage<K, V>::changeRecord(const K& key, const V& value)
{
if (!opened) {
throw Archive::Closed("changeRecord", name.toStdString());
@ -117,12 +117,10 @@ void Core::Storage<T>::changeRecord(const QString& key, const T& value)
QByteArray ba;
QDataStream ds(&ba, QIODevice::WriteOnly);
const std::string& id = key.toStdString();
ds << value;
MDB_val lmdbKey, lmdbData;
lmdbKey.mv_size = id.size();
lmdbKey.mv_data = (char*)id.c_str();
lmdbKey << key;
lmdbData.mv_size = ba.size();
lmdbData.mv_data = (uint8_t*)ba.data();
MDB_txn *txn;
@ -139,17 +137,15 @@ void Core::Storage<T>::changeRecord(const QString& key, const T& value)
}
}
template <class T>
T Core::Storage<T>::getRecord(const QString& key) const
template <class K, class V>
V Core::Storage<K, V>::getRecord(const K& key) const
{
if (!opened) {
throw Archive::Closed("addElement", name.toStdString());
}
const std::string& id = key.toStdString();
MDB_val lmdbKey, lmdbData;
lmdbKey.mv_size = id.size();
lmdbKey.mv_data = (char*)id.c_str();
lmdbKey << key;
MDB_txn *txn;
int rc;
@ -158,14 +154,14 @@ T Core::Storage<T>::getRecord(const QString& key) const
if (rc) {
mdb_txn_abort(txn);
if (rc == MDB_NOTFOUND) {
throw Archive::NotFound(id, name.toStdString());
throw Archive::NotFound(std::to_string(key), name.toStdString());
} else {
throw Archive::Unknown(name.toStdString(), mdb_strerror(rc));
}
} else {
QByteArray ba((char*)lmdbData.mv_data, lmdbData.mv_size);
QDataStream ds(&ba, QIODevice::ReadOnly);
T value;
V value;
ds >> value;
mdb_txn_abort(txn);
@ -173,17 +169,15 @@ T Core::Storage<T>::getRecord(const QString& key) const
}
}
template <class T>
void Core::Storage<T>::removeRecord(const QString& key)
template <class K, class V>
void Core::Storage<K, V>::removeRecord(const K& key)
{
if (!opened) {
throw Archive::Closed("addElement", name.toStdString());
}
const std::string& id = key.toStdString();
MDB_val lmdbKey;
lmdbKey.mv_size = id.size();
lmdbKey.mv_data = (char*)id.c_str();
lmdbKey << key;
MDB_txn *txn;
int rc;
@ -192,7 +186,7 @@ void Core::Storage<T>::removeRecord(const QString& key)
if (rc) {
mdb_txn_abort(txn);
if (rc == MDB_NOTFOUND) {
throw Archive::NotFound(id, name.toStdString());
throw Archive::NotFound(std::to_string(key), name.toStdString());
} else {
throw Archive::Unknown(name.toStdString(), mdb_strerror(rc));
}
@ -201,8 +195,32 @@ void Core::Storage<T>::removeRecord(const QString& key)
}
}
template <class T>
QString Core::Storage<T>::getName() const {
template <class K, class V>
QString Core::Storage<K, V>::getName() const {
return name;}
MDB_val& operator << (MDB_val& data, const QString& value) {
QByteArray ba = value.toUtf8();
data.mv_size = ba.size();
data.mv_data = ba.data();
return data;
}
MDB_val& operator >> (MDB_val& data, QString& value) {
value = QString::fromUtf8((const char*)data.mv_data, data.mv_size);
return data;
}
MDB_val& operator << (MDB_val& data, uint32_t& value) {
data.mv_size = 4;
data.mv_data = &value;
return data;
}
MDB_val& operator >> (MDB_val& data, uint32_t& value) {
std::memcpy(&value, data.mv_data, data.mv_size);
return data;
}
std::string std::to_string(const QString& str) {
return str.toStdString();
}
#endif //CORE_STORAGE_HPP