File: data_types.cpp

package info (click to toggle)
telegram-desktop 4.6.5%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 53,300 kB
  • sloc: cpp: 605,857; python: 3,978; ansic: 1,636; sh: 965; makefile: 841; objc: 652; javascript: 187; xml: 165
file content (155 lines) | stat: -rw-r--r-- 5,136 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
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 "data/data_types.h"

#include "ui/widgets/input_fields.h"
#include "storage/cache/storage_cache_types.h"
#include "base/openssl_help.h"

namespace Data {
namespace {

constexpr auto kDocumentCacheTag = 0x0000000000000100ULL;
constexpr auto kDocumentCacheMask = 0x00000000000000FFULL;
constexpr auto kDocumentThumbCacheTag = 0x0000000000000200ULL;
constexpr auto kDocumentThumbCacheMask = 0x00000000000000FFULL;
constexpr auto kAudioAlbumThumbCacheTag = 0x0000000000000300ULL;
constexpr auto kWebDocumentCacheTag = 0x0000020000000000ULL;
constexpr auto kUrlCacheTag = 0x0000030000000000ULL;
constexpr auto kGeoPointCacheTag = 0x0000040000000000ULL;

} // namespace

Storage::Cache::Key DocumentCacheKey(int32 dcId, uint64 id) {
	return Storage::Cache::Key{
		Data::kDocumentCacheTag | (uint64(dcId) & Data::kDocumentCacheMask),
		id
	};
}

Storage::Cache::Key DocumentThumbCacheKey(int32 dcId, uint64 id) {
	const auto part = (uint64(dcId) & Data::kDocumentThumbCacheMask);
	return Storage::Cache::Key{
		Data::kDocumentThumbCacheTag | part,
		id
	};
}

Storage::Cache::Key WebDocumentCacheKey(const WebFileLocation &location) {
	const auto CacheDcId = 4; // The default production value. Doesn't matter.
	const auto dcId = uint64(CacheDcId) & 0xFFULL;
	const auto &url = location.url();
	const auto hash = openssl::Sha256(bytes::make_span(url));
	const auto bytes = bytes::make_span(hash);
	const auto bytes1 = bytes.subspan(0, sizeof(uint32));
	const auto bytes2 = bytes.subspan(sizeof(uint32), sizeof(uint64));
	const auto part1 = *reinterpret_cast<const uint32*>(bytes1.data());
	const auto part2 = *reinterpret_cast<const uint64*>(bytes2.data());
	return Storage::Cache::Key{
		Data::kWebDocumentCacheTag | (dcId << 32) | part1,
		part2
	};
}

Storage::Cache::Key UrlCacheKey(const QString &location) {
	const auto url = location.toUtf8();
	const auto hash = openssl::Sha256(bytes::make_span(url));
	const auto bytes = bytes::make_span(hash);
	const auto bytes1 = bytes.subspan(0, sizeof(uint32));
	const auto bytes2 = bytes.subspan(sizeof(uint32), sizeof(uint64));
	const auto bytes3 = bytes.subspan(
		sizeof(uint32) + sizeof(uint64),
		sizeof(uint16));
	const auto part1 = *reinterpret_cast<const uint32*>(bytes1.data());
	const auto part2 = *reinterpret_cast<const uint64*>(bytes2.data());
	const auto part3 = *reinterpret_cast<const uint16*>(bytes3.data());
	return Storage::Cache::Key{
		Data::kUrlCacheTag | (uint64(part3) << 32) | part1,
		part2
	};
}

Storage::Cache::Key GeoPointCacheKey(const GeoPointLocation &location) {
	const auto zoomscale = ((uint32(location.zoom) & 0x0FU) << 8)
		| (uint32(location.scale) & 0x0FU);
	const auto widthheight = ((uint32(location.width) & 0xFFFFU) << 16)
		| (uint32(location.height) & 0xFFFFU);
	return Storage::Cache::Key{
		Data::kGeoPointCacheTag | (uint64(zoomscale) << 32) | widthheight,
		(uint64(base::SafeRound(
			std::abs(location.lat + 360.) * 1000000)) << 32)
		| uint64(base::SafeRound(std::abs(location.lon + 360.) * 1000000))
	};
}

Storage::Cache::Key AudioAlbumThumbCacheKey(
		const AudioAlbumThumbLocation &location) {
	return Storage::Cache::Key{
		Data::kAudioAlbumThumbCacheTag,
		location.documentId,
	};
}

} // namespace Data

void MessageCursor::fillFrom(not_null<const Ui::InputField*> field) {
	const auto cursor = field->textCursor();
	position = cursor.position();
	anchor = cursor.anchor();
	const auto top = field->scrollTop().current();
	scroll = (top != field->scrollTopMax()) ? top : QFIXED_MAX;
}

void MessageCursor::applyTo(not_null<Ui::InputField*> field) {
	auto cursor = field->textCursor();
	cursor.setPosition(anchor, QTextCursor::MoveAnchor);
	cursor.setPosition(position, QTextCursor::KeepAnchor);
	field->setTextCursor(cursor);
	field->scrollTo(scroll);
}

PeerId PeerFromMessage(const MTPmessage &message) {
	return message.match([](const MTPDmessageEmpty &) {
		return PeerId(0);
	}, [](const auto &data) {
		return peerFromMTP(data.vpeer_id());
	});
}

MTPDmessage::Flags FlagsFromMessage(const MTPmessage &message) {
	return message.match([](const MTPDmessageEmpty &) {
		return MTPDmessage::Flags(0);
	}, [](const MTPDmessage &data) {
		return data.vflags().v;
	}, [](const MTPDmessageService &data) {
		return mtpCastFlags(data.vflags().v);
	});
}

MsgId IdFromMessage(const MTPmessage &message) {
	return message.match([](const auto &data) {
		return data.vid().v;
	});
}

TimeId DateFromMessage(const MTPmessage &message) {
	return message.match([](const MTPDmessageEmpty &) {
		return TimeId(0);
	}, [](const auto &message) {
		return message.vdate().v;
	});
}

bool GoodStickerDimensions(int width, int height) {
	// Show all .webp (except very large ones) as stickers,
	// allow to open them in media viewer to see details.
	constexpr auto kLargetsStickerSide = 2560;
	return (width > 0)
		&& (height > 0)
		&& (width * height <= kLargetsStickerSide * kLargetsStickerSide);
}