tdesktop/Telegram/SourceFiles/core/core_settings_proxy.cpp

239 lines
5.7 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "core/core_settings_proxy.h"
#include "base/platform/base_platform_info.h"
#include "storage/serialize_common.h"
namespace Core {
namespace {
[[nodiscard]] qint32 ProxySettingsToInt(MTP::ProxyData::Settings settings) {
switch(settings) {
case MTP::ProxyData::Settings::System: return 0;
case MTP::ProxyData::Settings::Enabled: return 1;
case MTP::ProxyData::Settings::Disabled: return 2;
}
Unexpected("Bad type in ProxySettingsToInt");
}
[[nodiscard]] MTP::ProxyData::Settings IntToProxySettings(qint32 value) {
switch(value) {
case 0: return MTP::ProxyData::Settings::System;
case 1: return MTP::ProxyData::Settings::Enabled;
case 2: return MTP::ProxyData::Settings::Disabled;
}
Unexpected("Bad type in IntToProxySettings");
}
[[nodiscard]] MTP::ProxyData DeserializeProxyData(const QByteArray &data) {
QDataStream stream(data);
stream.setVersion(QDataStream::Qt_5_1);
qint32 proxyType, port;
MTP::ProxyData proxy;
stream
>> proxyType
>> proxy.host
>> port
>> proxy.user
>> proxy.password;
proxy.port = port;
proxy.type = [&] {
switch(proxyType) {
case 0: return MTP::ProxyData::Type::None;
case 1: return MTP::ProxyData::Type::Socks5;
case 2: return MTP::ProxyData::Type::Http;
case 3: return MTP::ProxyData::Type::Mtproto;
}
Unexpected("Bad type in DeserializeProxyData");
}();
return proxy;
}
[[nodiscard]] QByteArray SerializeProxyData(const MTP::ProxyData &proxy) {
auto result = QByteArray();
const auto size = 1 * sizeof(qint32)
+ Serialize::stringSize(proxy.host)
+ 1 * sizeof(qint32)
+ Serialize::stringSize(proxy.user)
+ Serialize::stringSize(proxy.password);
result.reserve(size);
{
const auto proxyType = [&] {
switch(proxy.type) {
case MTP::ProxyData::Type::None: return 0;
case MTP::ProxyData::Type::Socks5: return 1;
case MTP::ProxyData::Type::Http: return 2;
case MTP::ProxyData::Type::Mtproto: return 3;
}
Unexpected("Bad type in SerializeProxyData");
}();
QDataStream stream(&result, QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_5_1);
stream
<< qint32(proxyType)
<< proxy.host
<< qint32(proxy.port)
<< proxy.user
<< proxy.password;
}
return result;
}
} // namespace
SettingsProxy::SettingsProxy()
: _tryIPv6(!Platform::IsWindows()) {
}
QByteArray SettingsProxy::serialize() const {
auto result = QByteArray();
auto stream = QDataStream(&result, QIODevice::WriteOnly);
const auto serializedSelected = SerializeProxyData(_selected);
const auto serializedList = ranges::views::all(
_list
) | ranges::views::transform(SerializeProxyData) | ranges::to_vector;
const auto size = 3 * sizeof(qint32)
+ Serialize::bytearraySize(serializedSelected)
+ 1 * sizeof(qint32)
+ ranges::accumulate(
serializedList,
0,
ranges::plus(),
&Serialize::bytearraySize);
result.reserve(size);
stream.setVersion(QDataStream::Qt_5_1);
stream
<< qint32(_tryIPv6 ? 1 : 0)
<< qint32(_useProxyForCalls ? 1 : 0)
<< ProxySettingsToInt(_settings)
<< serializedSelected
<< qint32(_list.size());
for (const auto &i : serializedList) {
stream << i;
}
stream.device()->close();
return result;
}
bool SettingsProxy::setFromSerialized(const QByteArray &serialized) {
if (serialized.isEmpty()) {
return true;
}
auto stream = QDataStream(serialized);
auto tryIPv6 = qint32(_tryIPv6 ? 1 : 0);
auto useProxyForCalls = qint32(_useProxyForCalls ? 1 : 0);
auto settings = ProxySettingsToInt(_settings);
auto listCount = qint32(_list.size());
auto selectedProxy = QByteArray();
if (!stream.atEnd()) {
stream
>> tryIPv6
>> useProxyForCalls
>> settings
>> selectedProxy
>> listCount;
if (stream.status() == QDataStream::Ok) {
for (auto i = 0; i != listCount; ++i) {
QByteArray data;
stream >> data;
_list.push_back(DeserializeProxyData(data));
}
}
}
if (stream.status() != QDataStream::Ok) {
LOG(("App Error: "
"Bad data for Core::SettingsProxy::setFromSerialized()"));
return false;
}
_tryIPv6 = (tryIPv6 == 1);
_useProxyForCalls = (useProxyForCalls == 1);
_settings = IntToProxySettings(settings);
_selected = DeserializeProxyData(selectedProxy);
return true;
}
bool SettingsProxy::isEnabled() const {
return _settings == MTP::ProxyData::Settings::Enabled;
}
bool SettingsProxy::isSystem() const {
return _settings == MTP::ProxyData::Settings::System;
}
bool SettingsProxy::isDisabled() const {
return _settings == MTP::ProxyData::Settings::Disabled;
}
bool SettingsProxy::tryIPv6() const {
return _tryIPv6;
}
void SettingsProxy::setTryIPv6(bool value) {
_tryIPv6 = value;
}
bool SettingsProxy::useProxyForCalls() const {
return _useProxyForCalls;
}
void SettingsProxy::setUseProxyForCalls(bool value) {
_useProxyForCalls = value;
}
MTP::ProxyData::Settings SettingsProxy::settings() const {
return _settings;
}
void SettingsProxy::setSettings(MTP::ProxyData::Settings value) {
_settings = value;
}
MTP::ProxyData SettingsProxy::selected() const {
return _selected;
}
void SettingsProxy::setSelected(MTP::ProxyData value) {
_selected = value;
}
const std::vector<MTP::ProxyData> &SettingsProxy::list() const {
return _list;
}
std::vector<MTP::ProxyData> &SettingsProxy::list() {
return _list;
}
rpl::producer<> SettingsProxy::connectionTypeValue() const {
return _connectionTypeChanges.events_starting_with({});
}
rpl::producer<> SettingsProxy::connectionTypeChanges() const {
return _connectionTypeChanges.events();
}
void SettingsProxy::connectionTypeChangesNotify() {
_connectionTypeChanges.fire({});
}
} // namespace Core