2018-12-31 20:04:05 +01:00
|
|
|
//
|
2018-12-31 23:02:34 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2019
|
2018-12-31 20:04:05 +01:00
|
|
|
//
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
//
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "td/telegram/telegram_api.h"
|
|
|
|
|
2018-12-26 17:11:15 +01:00
|
|
|
#include "td/telegram/files/FileBitmask.h"
|
2019-01-19 22:54:29 +01:00
|
|
|
#include "td/telegram/files/FileType.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
#include "td/telegram/net/DcId.h"
|
2019-06-19 02:18:44 +02:00
|
|
|
#include "td/telegram/PhotoSizeSource.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2018-12-08 23:00:27 +01:00
|
|
|
#include "td/utils/base64.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
#include "td/utils/buffer.h"
|
|
|
|
#include "td/utils/common.h"
|
|
|
|
#include "td/utils/format.h"
|
|
|
|
#include "td/utils/logging.h"
|
2019-06-12 15:05:22 +02:00
|
|
|
#include "td/utils/misc.h"
|
2018-12-31 20:04:05 +01:00
|
|
|
#include "td/utils/Slice.h"
|
|
|
|
#include "td/utils/StringBuilder.h"
|
|
|
|
#include "td/utils/Variant.h"
|
|
|
|
|
|
|
|
#include <tuple>
|
2019-01-31 00:57:14 +01:00
|
|
|
#include <utility>
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
namespace td {
|
2019-01-30 22:37:38 +01:00
|
|
|
|
2019-01-30 17:08:50 +01:00
|
|
|
class FileReferenceView {
|
|
|
|
public:
|
2019-01-31 09:33:35 +01:00
|
|
|
static Slice invalid_file_reference() {
|
|
|
|
return Slice("#");
|
|
|
|
}
|
2019-01-30 17:08:50 +01:00
|
|
|
};
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
struct EmptyRemoteFileLocation {
|
|
|
|
template <class StorerT>
|
|
|
|
void store(StorerT &storer) const {
|
|
|
|
}
|
|
|
|
template <class ParserT>
|
|
|
|
void parse(ParserT &parser) {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator==(const EmptyRemoteFileLocation &lhs, const EmptyRemoteFileLocation &rhs) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const EmptyRemoteFileLocation &lhs, const EmptyRemoteFileLocation &rhs) {
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct PartialRemoteFileLocation {
|
|
|
|
int64 file_id_;
|
|
|
|
int32 part_count_;
|
|
|
|
int32 part_size_;
|
|
|
|
int32 ready_part_count_;
|
|
|
|
int32 is_big_;
|
2018-11-11 14:35:51 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator==(const PartialRemoteFileLocation &lhs, const PartialRemoteFileLocation &rhs) {
|
|
|
|
return lhs.file_id_ == rhs.file_id_ && lhs.part_count_ == rhs.part_count_ && lhs.part_size_ == rhs.part_size_ &&
|
|
|
|
lhs.ready_part_count_ == rhs.ready_part_count_ && lhs.is_big_ == rhs.is_big_;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const PartialRemoteFileLocation &lhs, const PartialRemoteFileLocation &rhs) {
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
2018-12-27 17:50:45 +01:00
|
|
|
inline StringBuilder &operator<<(StringBuilder &sb, const PartialRemoteFileLocation &location) {
|
|
|
|
return sb << '[' << (location.is_big_ ? "Big" : "Small") << " partial remote location with " << location.part_count_
|
|
|
|
<< " parts of size " << location.part_size_ << " with " << location.ready_part_count_ << " ready parts]";
|
|
|
|
}
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
struct PhotoRemoteFileLocation {
|
|
|
|
int64 id_;
|
|
|
|
int64 access_hash_;
|
|
|
|
int64 volume_id_;
|
|
|
|
int32 local_id_;
|
2019-06-11 12:10:14 +02:00
|
|
|
PhotoSizeSource source_;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
struct AsKey {
|
|
|
|
const PhotoRemoteFileLocation &key;
|
2019-02-07 22:00:26 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
AsKey as_key() const {
|
|
|
|
return AsKey{*this};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator<(const PhotoRemoteFileLocation &other) const {
|
|
|
|
return std::tie(id_, volume_id_, local_id_) < std::tie(other.id_, other.volume_id_, other.local_id_);
|
|
|
|
}
|
|
|
|
bool operator==(const PhotoRemoteFileLocation &other) const {
|
|
|
|
return std::tie(id_, volume_id_, local_id_) == std::tie(other.id_, other.volume_id_, other.local_id_);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline StringBuilder &operator<<(StringBuilder &string_builder, const PhotoRemoteFileLocation &location) {
|
|
|
|
return string_builder << "[id = " << location.id_ << ", access_hash = " << location.access_hash_
|
2018-04-11 16:21:24 +02:00
|
|
|
<< ", volume_id = " << location.volume_id_ << ", local_id = " << location.local_id_ << "]";
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
struct WebRemoteFileLocation {
|
|
|
|
string url_;
|
|
|
|
int64 access_hash_;
|
|
|
|
|
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
struct AsKey {
|
|
|
|
const WebRemoteFileLocation &key;
|
2019-02-07 22:00:26 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
AsKey as_key() const {
|
|
|
|
return AsKey{*this};
|
|
|
|
}
|
2019-02-07 22:00:26 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
bool operator<(const WebRemoteFileLocation &other) const {
|
|
|
|
return url_ < other.url_;
|
|
|
|
}
|
|
|
|
bool operator==(const WebRemoteFileLocation &other) const {
|
|
|
|
return url_ == other.url_;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline StringBuilder &operator<<(StringBuilder &string_builder, const WebRemoteFileLocation &location) {
|
|
|
|
return string_builder << "[url = " << location.url_ << ", access_hash = " << location.access_hash_ << "]";
|
|
|
|
}
|
|
|
|
|
|
|
|
struct CommonRemoteFileLocation {
|
|
|
|
int64 id_;
|
|
|
|
int64 access_hash_;
|
|
|
|
|
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
struct AsKey {
|
|
|
|
const CommonRemoteFileLocation &key;
|
2019-02-07 22:00:26 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
AsKey as_key() const {
|
|
|
|
return AsKey{*this};
|
|
|
|
}
|
2019-02-07 22:00:26 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
bool operator<(const CommonRemoteFileLocation &other) const {
|
|
|
|
return std::tie(id_) < std::tie(other.id_);
|
|
|
|
}
|
|
|
|
bool operator==(const CommonRemoteFileLocation &other) const {
|
|
|
|
return std::tie(id_) == std::tie(other.id_);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline StringBuilder &operator<<(StringBuilder &string_builder, const CommonRemoteFileLocation &location) {
|
|
|
|
return string_builder << "[id = " << location.id_ << ", access_hash = " << location.access_hash_ << "]";
|
|
|
|
}
|
|
|
|
|
|
|
|
class FullRemoteFileLocation {
|
|
|
|
public:
|
2018-01-20 15:57:52 +01:00
|
|
|
FileType file_type_{FileType::None};
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
static constexpr int32 WEB_LOCATION_FLAG = 1 << 24;
|
2018-12-05 10:32:31 +01:00
|
|
|
static constexpr int32 FILE_REFERENCE_FLAG = 1 << 25;
|
2018-12-31 20:04:05 +01:00
|
|
|
bool web_location_flag_{false};
|
|
|
|
DcId dc_id_;
|
2019-05-09 04:01:45 +02:00
|
|
|
string file_reference_;
|
2018-04-19 15:08:30 +02:00
|
|
|
enum class LocationType : int32 { Web, Photo, Common, None };
|
2018-12-31 20:04:05 +01:00
|
|
|
Variant<WebRemoteFileLocation, PhotoRemoteFileLocation, CommonRemoteFileLocation> variant_;
|
|
|
|
|
|
|
|
LocationType location_type() const {
|
|
|
|
if (is_web()) {
|
|
|
|
return LocationType::Web;
|
|
|
|
}
|
2018-01-20 15:57:52 +01:00
|
|
|
switch (file_type_) {
|
2018-12-31 20:04:05 +01:00
|
|
|
case FileType::Photo:
|
|
|
|
case FileType::ProfilePhoto:
|
|
|
|
case FileType::Thumbnail:
|
|
|
|
case FileType::EncryptedThumbnail:
|
|
|
|
case FileType::Wallpaper:
|
|
|
|
return LocationType::Photo;
|
|
|
|
case FileType::Video:
|
|
|
|
case FileType::VoiceNote:
|
|
|
|
case FileType::Document:
|
|
|
|
case FileType::Sticker:
|
|
|
|
case FileType::Audio:
|
|
|
|
case FileType::Animation:
|
|
|
|
case FileType::Encrypted:
|
|
|
|
case FileType::VideoNote:
|
2018-03-27 15:11:15 +02:00
|
|
|
case FileType::SecureRaw:
|
|
|
|
case FileType::Secure:
|
2019-05-07 04:51:56 +02:00
|
|
|
case FileType::Background:
|
2018-12-31 20:04:05 +01:00
|
|
|
return LocationType::Common;
|
|
|
|
case FileType::None:
|
|
|
|
case FileType::Size:
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
case FileType::Temp:
|
|
|
|
return LocationType::None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WebRemoteFileLocation &web() {
|
|
|
|
return variant_.get<WebRemoteFileLocation>();
|
|
|
|
}
|
|
|
|
PhotoRemoteFileLocation &photo() {
|
|
|
|
return variant_.get<PhotoRemoteFileLocation>();
|
|
|
|
}
|
|
|
|
CommonRemoteFileLocation &common() {
|
|
|
|
return variant_.get<CommonRemoteFileLocation>();
|
|
|
|
}
|
|
|
|
const WebRemoteFileLocation &web() const {
|
|
|
|
return variant_.get<WebRemoteFileLocation>();
|
|
|
|
}
|
|
|
|
const PhotoRemoteFileLocation &photo() const {
|
|
|
|
return variant_.get<PhotoRemoteFileLocation>();
|
|
|
|
}
|
|
|
|
const CommonRemoteFileLocation &common() const {
|
|
|
|
return variant_.get<CommonRemoteFileLocation>();
|
|
|
|
}
|
|
|
|
|
|
|
|
friend StringBuilder &operator<<(StringBuilder &string_builder,
|
|
|
|
const FullRemoteFileLocation &full_remote_file_location);
|
|
|
|
|
2019-01-20 16:26:51 +01:00
|
|
|
int32 key_type() const {
|
|
|
|
auto type = static_cast<int32>(file_type_);
|
|
|
|
if (is_web()) {
|
|
|
|
type |= WEB_LOCATION_FLAG;
|
|
|
|
}
|
|
|
|
return type;
|
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
int32 full_type() const {
|
2018-01-20 15:57:52 +01:00
|
|
|
auto type = static_cast<int32>(file_type_);
|
2018-12-31 20:04:05 +01:00
|
|
|
if (is_web()) {
|
|
|
|
type |= WEB_LOCATION_FLAG;
|
|
|
|
}
|
2018-12-05 10:32:31 +01:00
|
|
|
if (!file_reference_.empty()) {
|
|
|
|
type |= FILE_REFERENCE_FLAG;
|
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
2019-06-08 11:26:35 +02:00
|
|
|
void check_file_reference() {
|
2019-06-17 04:37:57 +02:00
|
|
|
if (file_reference_ == FileReferenceView::invalid_file_reference()) {
|
2019-06-08 11:26:35 +02:00
|
|
|
LOG(ERROR) << "Tried to register file with invalid file reference";
|
|
|
|
file_reference_.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
public:
|
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
struct AsKey {
|
|
|
|
const FullRemoteFileLocation &key;
|
2019-02-07 22:00:26 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
AsKey as_key() const {
|
|
|
|
return AsKey{*this};
|
|
|
|
}
|
|
|
|
|
|
|
|
DcId get_dc_id() const {
|
2018-06-25 23:10:53 +02:00
|
|
|
CHECK(!is_web());
|
2018-12-31 20:04:05 +01:00
|
|
|
return dc_id_;
|
|
|
|
}
|
2019-01-31 00:57:14 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
int64 get_access_hash() const {
|
|
|
|
switch (location_type()) {
|
|
|
|
case LocationType::Photo:
|
|
|
|
return photo().access_hash_;
|
|
|
|
case LocationType::Common:
|
|
|
|
return common().access_hash_;
|
|
|
|
case LocationType::Web:
|
|
|
|
return web().access_hash_;
|
|
|
|
case LocationType::None:
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2019-01-31 00:57:14 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
int64 get_id() const {
|
|
|
|
switch (location_type()) {
|
|
|
|
case LocationType::Photo:
|
|
|
|
return photo().id_;
|
|
|
|
case LocationType::Common:
|
|
|
|
return common().id_;
|
|
|
|
case LocationType::Web:
|
|
|
|
case LocationType::None:
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2019-06-18 17:40:46 +02:00
|
|
|
|
|
|
|
PhotoSizeSource get_source() const {
|
|
|
|
switch (location_type()) {
|
|
|
|
case LocationType::Photo:
|
|
|
|
return photo().source_;
|
|
|
|
case LocationType::Common:
|
|
|
|
case LocationType::Web:
|
2019-06-19 02:53:11 +02:00
|
|
|
return PhotoSizeSource(0);
|
2019-06-18 17:40:46 +02:00
|
|
|
case LocationType::None:
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
2019-06-19 02:53:11 +02:00
|
|
|
return PhotoSizeSource(0);
|
2019-06-18 17:40:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-27 16:08:24 +01:00
|
|
|
void clear_file_reference() {
|
2019-05-09 04:01:45 +02:00
|
|
|
file_reference_.clear();
|
2019-02-27 16:08:24 +01:00
|
|
|
}
|
2019-01-31 00:57:14 +01:00
|
|
|
|
2018-12-05 10:32:31 +01:00
|
|
|
bool delete_file_reference(Slice bad_file_reference) {
|
2019-06-17 04:37:57 +02:00
|
|
|
if (file_reference_ != FileReferenceView::invalid_file_reference() && file_reference_ == bad_file_reference) {
|
|
|
|
file_reference_ = FileReferenceView::invalid_file_reference().str();
|
|
|
|
return true;
|
2018-12-05 10:32:31 +01:00
|
|
|
}
|
2019-06-17 04:37:57 +02:00
|
|
|
return false;
|
2018-12-05 10:32:31 +01:00
|
|
|
}
|
2019-06-18 17:40:46 +02:00
|
|
|
|
2019-06-17 04:37:57 +02:00
|
|
|
bool has_file_reference() const {
|
|
|
|
return file_reference_ != FileReferenceView::invalid_file_reference();
|
2018-12-08 23:00:27 +01:00
|
|
|
}
|
2019-06-18 17:40:46 +02:00
|
|
|
|
2019-06-17 04:37:57 +02:00
|
|
|
Slice get_file_reference() const {
|
2018-12-05 10:32:31 +01:00
|
|
|
return file_reference_;
|
|
|
|
}
|
2019-01-31 00:57:14 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
string get_url() const {
|
|
|
|
if (is_web()) {
|
|
|
|
return web().url_;
|
|
|
|
}
|
|
|
|
|
|
|
|
return string();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool is_web() const {
|
|
|
|
return web_location_flag_;
|
|
|
|
}
|
|
|
|
bool is_photo() const {
|
|
|
|
return location_type() == LocationType::Photo;
|
|
|
|
}
|
|
|
|
bool is_common() const {
|
|
|
|
return location_type() == LocationType::Common;
|
|
|
|
}
|
2018-03-27 15:11:15 +02:00
|
|
|
bool is_encrypted_secret() const {
|
2018-01-20 15:57:52 +01:00
|
|
|
return file_type_ == FileType::Encrypted;
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2018-03-27 15:11:15 +02:00
|
|
|
bool is_encrypted_secure() const {
|
|
|
|
return file_type_ == FileType::Secure;
|
|
|
|
}
|
|
|
|
bool is_encrypted_any() const {
|
|
|
|
return is_encrypted_secret() || is_encrypted_secure();
|
|
|
|
}
|
|
|
|
bool is_secure() const {
|
|
|
|
return file_type_ == FileType::SecureRaw || file_type_ == FileType::Secure;
|
|
|
|
}
|
|
|
|
bool is_document() const {
|
|
|
|
return is_common() && !is_secure() && !is_encrypted_secret();
|
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2018-11-06 15:24:32 +01:00
|
|
|
#define as_input_web_file_location() as_input_web_file_location_impl(__FILE__, __LINE__)
|
|
|
|
tl_object_ptr<telegram_api::inputWebFileLocation> as_input_web_file_location_impl(const char *file, int line) const {
|
2019-02-12 17:17:20 +01:00
|
|
|
LOG_CHECK(is_web()) << file << ' ' << line;
|
2018-12-31 20:04:05 +01:00
|
|
|
return make_tl_object<telegram_api::inputWebFileLocation>(web().url_, web().access_hash_);
|
|
|
|
}
|
2018-11-06 15:24:32 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
tl_object_ptr<telegram_api::InputFileLocation> as_input_file_location() const {
|
|
|
|
switch (location_type()) {
|
2019-06-20 02:51:37 +02:00
|
|
|
case LocationType::Photo:
|
2019-06-18 18:56:59 +02:00
|
|
|
switch (photo().source_.get_type()) {
|
2019-06-19 02:53:11 +02:00
|
|
|
case PhotoSizeSource::Type::Legacy:
|
|
|
|
return make_tl_object<telegram_api::inputFileLocation>(
|
|
|
|
photo().volume_id_, photo().local_id_, photo().source_.legacy().secret, BufferSlice(file_reference_));
|
2019-06-11 12:10:14 +02:00
|
|
|
case PhotoSizeSource::Type::Thumbnail: {
|
|
|
|
auto &thumbnail = photo().source_.thumbnail();
|
2019-06-18 18:45:26 +02:00
|
|
|
switch (thumbnail.file_type) {
|
2019-06-11 12:10:14 +02:00
|
|
|
case FileType::Photo:
|
|
|
|
return make_tl_object<telegram_api::inputPhotoFileLocation>(
|
2019-06-17 04:37:57 +02:00
|
|
|
photo().id_, photo().access_hash_, BufferSlice(file_reference_),
|
2019-06-12 13:42:06 +02:00
|
|
|
std::string(1, static_cast<char>(narrow_cast<uint8>(thumbnail.thumbnail_type))));
|
2019-06-11 12:10:14 +02:00
|
|
|
case FileType::Thumbnail:
|
|
|
|
return make_tl_object<telegram_api::inputDocumentFileLocation>(
|
2019-06-17 04:37:57 +02:00
|
|
|
photo().id_, photo().access_hash_, BufferSlice(file_reference_),
|
2019-06-12 13:42:06 +02:00
|
|
|
std::string(1, static_cast<char>(narrow_cast<uint8>(thumbnail.thumbnail_type))));
|
2019-06-11 12:10:14 +02:00
|
|
|
}
|
2019-07-01 18:52:48 +02:00
|
|
|
break;
|
2019-06-11 12:10:14 +02:00
|
|
|
}
|
2019-06-20 03:35:08 +02:00
|
|
|
case PhotoSizeSource::Type::DialogPhotoSmall:
|
|
|
|
case PhotoSizeSource::Type::DialogPhotoBig: {
|
2019-06-11 12:10:14 +02:00
|
|
|
auto &dialog_photo = photo().source_.dialog_photo();
|
2019-06-20 03:35:08 +02:00
|
|
|
bool is_big = photo().source_.get_type() == PhotoSizeSource::Type::DialogPhotoBig;
|
2019-06-11 12:10:14 +02:00
|
|
|
return make_tl_object<telegram_api::inputPeerPhotoFileLocation>(
|
2019-06-20 03:35:08 +02:00
|
|
|
is_big * telegram_api::inputPeerPhotoFileLocation::Flags::BIG_MASK, false /*ignored*/,
|
2019-06-18 18:17:31 +02:00
|
|
|
dialog_photo.get_input_peer(), photo().volume_id_, photo().local_id_);
|
2019-06-11 12:10:14 +02:00
|
|
|
}
|
|
|
|
case PhotoSizeSource::Type::StickerSetThumbnail: {
|
|
|
|
auto &sticker_set_thumbnail = photo().source_.sticker_set_thumbnail();
|
2019-06-18 17:59:32 +02:00
|
|
|
return make_tl_object<telegram_api::inputStickerSetThumb>(sticker_set_thumbnail.get_input_sticker_set(),
|
|
|
|
photo().volume_id_, photo().local_id_);
|
2019-06-11 12:10:14 +02:00
|
|
|
}
|
2019-06-20 02:51:37 +02:00
|
|
|
default:
|
|
|
|
break;
|
2019-06-11 12:10:14 +02:00
|
|
|
}
|
2019-06-20 02:51:37 +02:00
|
|
|
UNREACHABLE();
|
|
|
|
return nullptr;
|
2018-12-31 20:04:05 +01:00
|
|
|
case LocationType::Common:
|
2018-03-27 15:11:15 +02:00
|
|
|
if (is_encrypted_secret()) {
|
2018-12-31 20:04:05 +01:00
|
|
|
return make_tl_object<telegram_api::inputEncryptedFileLocation>(common().id_, common().access_hash_);
|
2018-03-27 15:11:15 +02:00
|
|
|
} else if (is_secure()) {
|
|
|
|
return make_tl_object<telegram_api::inputSecureFileLocation>(common().id_, common().access_hash_);
|
2018-12-31 20:04:05 +01:00
|
|
|
} else {
|
2019-06-17 04:37:57 +02:00
|
|
|
return make_tl_object<telegram_api::inputDocumentFileLocation>(common().id_, common().access_hash_,
|
|
|
|
BufferSlice(file_reference_), string());
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
case LocationType::Web:
|
|
|
|
case LocationType::None:
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-06 15:24:32 +01:00
|
|
|
#define as_input_document() as_input_document_impl(__FILE__, __LINE__)
|
2019-01-23 20:20:48 +01:00
|
|
|
tl_object_ptr<telegram_api::inputDocument> as_input_document_impl(const char *file, int line) const {
|
2019-02-12 17:17:20 +01:00
|
|
|
LOG_CHECK(is_common()) << file << ' ' << line;
|
|
|
|
LOG_CHECK(is_document()) << file << ' ' << line;
|
2018-12-05 10:32:31 +01:00
|
|
|
return make_tl_object<telegram_api::inputDocument>(common().id_, common().access_hash_,
|
2019-06-17 04:37:57 +02:00
|
|
|
BufferSlice(file_reference_));
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
2018-11-06 15:24:32 +01:00
|
|
|
#define as_input_photo() as_input_photo_impl(__FILE__, __LINE__)
|
2019-01-23 20:20:48 +01:00
|
|
|
tl_object_ptr<telegram_api::inputPhoto> as_input_photo_impl(const char *file, int line) const {
|
2019-02-12 17:17:20 +01:00
|
|
|
LOG_CHECK(is_photo()) << file << ' ' << line;
|
2019-06-17 04:37:57 +02:00
|
|
|
return make_tl_object<telegram_api::inputPhoto>(photo().id_, photo().access_hash_, BufferSlice(file_reference_));
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
2019-01-23 20:20:48 +01:00
|
|
|
tl_object_ptr<telegram_api::inputEncryptedFile> as_input_encrypted_file() const {
|
2018-11-06 15:24:32 +01:00
|
|
|
CHECK(is_encrypted_secret());
|
2018-12-31 20:04:05 +01:00
|
|
|
return make_tl_object<telegram_api::inputEncryptedFile>(common().id_, common().access_hash_);
|
|
|
|
}
|
2018-11-06 15:24:32 +01:00
|
|
|
|
|
|
|
#define as_input_secure_file() as_input_secure_file_impl(__FILE__, __LINE__)
|
2019-01-23 20:20:48 +01:00
|
|
|
tl_object_ptr<telegram_api::inputSecureFile> as_input_secure_file_impl(const char *file, int line) const {
|
2019-02-12 17:17:20 +01:00
|
|
|
LOG_CHECK(is_secure()) << file << ' ' << line;
|
2018-03-27 15:11:15 +02:00
|
|
|
return make_tl_object<telegram_api::inputSecureFile>(common().id_, common().access_hash_);
|
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
// TODO: this constructor is just for immediate unserialize
|
|
|
|
FullRemoteFileLocation() = default;
|
2019-06-08 11:26:35 +02:00
|
|
|
|
|
|
|
// photo
|
|
|
|
FullRemoteFileLocation(const PhotoSizeSource &source, int64 id, int64 access_hash, int32 local_id, int64 volume_id,
|
|
|
|
DcId dc_id, std::string file_reference)
|
2019-06-19 02:18:44 +02:00
|
|
|
: file_type_(source.get_file_type())
|
2018-12-31 20:04:05 +01:00
|
|
|
, dc_id_(dc_id)
|
2019-06-17 04:37:57 +02:00
|
|
|
, file_reference_(std::move(file_reference))
|
2019-06-19 02:53:11 +02:00
|
|
|
, variant_(PhotoRemoteFileLocation{id, access_hash, volume_id, local_id, source}) {
|
2018-12-31 20:04:05 +01:00
|
|
|
CHECK(is_photo());
|
2019-06-08 11:26:35 +02:00
|
|
|
check_file_reference();
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2019-06-08 11:26:35 +02:00
|
|
|
|
|
|
|
// document
|
2018-12-05 10:32:31 +01:00
|
|
|
FullRemoteFileLocation(FileType file_type, int64 id, int64 access_hash, DcId dc_id, std::string file_reference)
|
|
|
|
: file_type_(file_type)
|
|
|
|
, dc_id_(dc_id)
|
2019-06-17 04:37:57 +02:00
|
|
|
, file_reference_(std::move(file_reference))
|
2018-12-05 10:32:31 +01:00
|
|
|
, variant_(CommonRemoteFileLocation{id, access_hash}) {
|
2018-12-31 20:04:05 +01:00
|
|
|
CHECK(is_common());
|
2019-06-08 11:26:35 +02:00
|
|
|
check_file_reference();
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2019-06-08 11:26:35 +02:00
|
|
|
|
|
|
|
// web document
|
2018-06-25 23:10:53 +02:00
|
|
|
FullRemoteFileLocation(FileType file_type, string url, int64 access_hash)
|
2018-01-20 15:57:52 +01:00
|
|
|
: file_type_(file_type)
|
2018-12-31 20:04:05 +01:00
|
|
|
, web_location_flag_{true}
|
2018-06-25 23:10:53 +02:00
|
|
|
, dc_id_()
|
2018-12-31 20:04:05 +01:00
|
|
|
, variant_(WebRemoteFileLocation{std::move(url), access_hash}) {
|
|
|
|
CHECK(is_web());
|
|
|
|
CHECK(!web().url_.empty());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator<(const FullRemoteFileLocation &other) const {
|
2019-01-20 16:26:51 +01:00
|
|
|
if (key_type() != other.key_type()) {
|
|
|
|
return key_type() < other.key_type();
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
if (dc_id_ != other.dc_id_) {
|
|
|
|
return dc_id_ < other.dc_id_;
|
|
|
|
}
|
|
|
|
switch (location_type()) {
|
|
|
|
case LocationType::Photo:
|
|
|
|
return photo() < other.photo();
|
|
|
|
case LocationType::Common:
|
|
|
|
return common() < other.common();
|
|
|
|
case LocationType::Web:
|
|
|
|
return web() < other.web();
|
|
|
|
case LocationType::None:
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool operator==(const FullRemoteFileLocation &other) const {
|
2019-01-20 16:26:51 +01:00
|
|
|
if (key_type() != other.key_type()) {
|
2018-12-31 20:04:05 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (dc_id_ != other.dc_id_) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
switch (location_type()) {
|
|
|
|
case LocationType::Photo:
|
|
|
|
return photo() == other.photo();
|
|
|
|
case LocationType::Common:
|
|
|
|
return common() == other.common();
|
|
|
|
case LocationType::Web:
|
|
|
|
return web() == other.web();
|
|
|
|
case LocationType::None:
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const int32 KEY_MAGIC = 0x64374632;
|
2019-01-31 00:57:14 +01:00
|
|
|
};
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
inline StringBuilder &operator<<(StringBuilder &string_builder,
|
|
|
|
const FullRemoteFileLocation &full_remote_file_location) {
|
2018-11-15 22:25:08 +01:00
|
|
|
string_builder << "[" << full_remote_file_location.file_type_;
|
2018-06-25 23:10:53 +02:00
|
|
|
if (!full_remote_file_location.is_web()) {
|
|
|
|
string_builder << ", " << full_remote_file_location.get_dc_id();
|
|
|
|
}
|
2018-12-05 10:32:31 +01:00
|
|
|
if (!full_remote_file_location.file_reference_.empty()) {
|
2019-06-17 04:37:57 +02:00
|
|
|
string_builder << ", " << tag("file_reference", base64_encode(full_remote_file_location.file_reference_));
|
2018-12-05 10:32:31 +01:00
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2018-06-25 23:10:53 +02:00
|
|
|
string_builder << ", location = ";
|
2018-12-31 20:04:05 +01:00
|
|
|
if (full_remote_file_location.is_web()) {
|
|
|
|
string_builder << full_remote_file_location.web();
|
|
|
|
} else if (full_remote_file_location.is_photo()) {
|
|
|
|
string_builder << full_remote_file_location.photo();
|
|
|
|
} else if (full_remote_file_location.is_common()) {
|
|
|
|
string_builder << full_remote_file_location.common();
|
|
|
|
}
|
|
|
|
|
|
|
|
return string_builder << "]";
|
|
|
|
}
|
|
|
|
|
2018-01-20 15:06:22 +01:00
|
|
|
class RemoteFileLocation {
|
|
|
|
public:
|
|
|
|
enum class Type : int32 { Empty, Partial, Full };
|
2018-01-20 15:57:52 +01:00
|
|
|
|
|
|
|
Type type() const {
|
2018-01-20 16:16:51 +01:00
|
|
|
return static_cast<Type>(variant_.get_offset());
|
2018-01-20 15:57:52 +01:00
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
PartialRemoteFileLocation &partial() {
|
|
|
|
return variant_.get<1>();
|
|
|
|
}
|
|
|
|
FullRemoteFileLocation &full() {
|
|
|
|
return variant_.get<2>();
|
|
|
|
}
|
|
|
|
const PartialRemoteFileLocation &partial() const {
|
|
|
|
return variant_.get<1>();
|
|
|
|
}
|
|
|
|
const FullRemoteFileLocation &full() const {
|
|
|
|
return variant_.get<2>();
|
|
|
|
}
|
2019-02-07 22:00:26 +01:00
|
|
|
|
|
|
|
template <class StorerT>
|
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2018-01-20 16:16:51 +01:00
|
|
|
RemoteFileLocation() : variant_{EmptyRemoteFileLocation{}} {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2018-01-20 16:16:51 +01:00
|
|
|
explicit RemoteFileLocation(const FullRemoteFileLocation &full) : variant_(full) {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2018-01-20 16:16:51 +01:00
|
|
|
explicit RemoteFileLocation(const PartialRemoteFileLocation &partial) : variant_(partial) {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2018-01-20 15:17:58 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
Variant<EmptyRemoteFileLocation, PartialRemoteFileLocation, FullRemoteFileLocation> variant_;
|
|
|
|
|
|
|
|
friend bool operator==(const RemoteFileLocation &lhs, const RemoteFileLocation &rhs);
|
2018-12-27 02:36:20 +01:00
|
|
|
|
|
|
|
bool is_empty() const {
|
|
|
|
switch (type()) {
|
|
|
|
case Type::Empty:
|
|
|
|
return true;
|
|
|
|
case Type::Partial:
|
|
|
|
return partial().ready_part_count_ == 0;
|
|
|
|
case Type::Full:
|
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator==(const RemoteFileLocation &lhs, const RemoteFileLocation &rhs) {
|
2018-12-27 02:36:20 +01:00
|
|
|
if (lhs.is_empty() && rhs.is_empty()) {
|
|
|
|
return true;
|
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
return lhs.variant_ == rhs.variant_;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const RemoteFileLocation &lhs, const RemoteFileLocation &rhs) {
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct EmptyLocalFileLocation {
|
|
|
|
template <class StorerT>
|
|
|
|
void store(StorerT &storer) const {
|
|
|
|
}
|
|
|
|
template <class ParserT>
|
|
|
|
void parse(ParserT &parser) {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator==(const EmptyLocalFileLocation &lhs, const EmptyLocalFileLocation &rhs) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const EmptyLocalFileLocation &lhs, const EmptyLocalFileLocation &rhs) {
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct PartialLocalFileLocation {
|
2018-01-20 15:57:52 +01:00
|
|
|
FileType file_type_;
|
2018-01-20 15:06:22 +01:00
|
|
|
int32 part_size_;
|
2018-12-26 17:11:15 +01:00
|
|
|
string path_;
|
2018-12-31 20:04:05 +01:00
|
|
|
string iv_;
|
2018-11-11 12:38:04 +01:00
|
|
|
string ready_bitmask_;
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator==(const PartialLocalFileLocation &lhs, const PartialLocalFileLocation &rhs) {
|
2018-01-20 15:57:52 +01:00
|
|
|
return lhs.file_type_ == rhs.file_type_ && lhs.path_ == rhs.path_ && lhs.part_size_ == rhs.part_size_ &&
|
2018-11-11 12:38:04 +01:00
|
|
|
lhs.iv_ == rhs.iv_ && lhs.ready_bitmask_ == rhs.ready_bitmask_;
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const PartialLocalFileLocation &lhs, const PartialLocalFileLocation &rhs) {
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
2018-12-27 18:46:28 +01:00
|
|
|
inline StringBuilder &operator<<(StringBuilder &sb, const PartialLocalFileLocation &location) {
|
|
|
|
return sb << "[partial local location of " << location.file_type_ << " with part size " << location.part_size_
|
|
|
|
<< " and ready parts " << Bitmask(Bitmask::Decode{}, location.ready_bitmask_) << "] at \"" << location.path_
|
|
|
|
<< '"';
|
|
|
|
}
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
struct FullLocalFileLocation {
|
2018-01-20 15:57:52 +01:00
|
|
|
FileType file_type_;
|
2018-12-31 20:04:05 +01:00
|
|
|
string path_;
|
|
|
|
uint64 mtime_nsec_;
|
|
|
|
|
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
const FullLocalFileLocation &as_key() const {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: remove this constructor
|
2018-01-20 15:57:52 +01:00
|
|
|
FullLocalFileLocation() : file_type_(FileType::Photo) {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
FullLocalFileLocation(FileType file_type, string path, uint64 mtime_nsec)
|
2018-01-20 15:57:52 +01:00
|
|
|
: file_type_(file_type), path_(std::move(path)), mtime_nsec_(mtime_nsec) {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static const int32 KEY_MAGIC = 0x84373817;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator<(const FullLocalFileLocation &lhs, const FullLocalFileLocation &rhs) {
|
2018-01-20 15:57:52 +01:00
|
|
|
return std::tie(lhs.file_type_, lhs.mtime_nsec_, lhs.path_) < std::tie(rhs.file_type_, rhs.mtime_nsec_, rhs.path_);
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator==(const FullLocalFileLocation &lhs, const FullLocalFileLocation &rhs) {
|
2018-01-20 15:57:52 +01:00
|
|
|
return std::tie(lhs.file_type_, lhs.mtime_nsec_, lhs.path_) == std::tie(rhs.file_type_, rhs.mtime_nsec_, rhs.path_);
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const FullLocalFileLocation &lhs, const FullLocalFileLocation &rhs) {
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline StringBuilder &operator<<(StringBuilder &sb, const FullLocalFileLocation &location) {
|
2019-01-01 18:35:08 +01:00
|
|
|
return sb << "[full local location of " << location.file_type_ << "] at \"" << location.path_ << '"';
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
2019-01-02 19:17:08 +01:00
|
|
|
struct PartialLocalFileLocationPtr {
|
|
|
|
unique_ptr<PartialLocalFileLocation> location_; // must never be equal to nullptr
|
|
|
|
|
|
|
|
PartialLocalFileLocationPtr() : location_(make_unique<PartialLocalFileLocation>()) {
|
|
|
|
}
|
|
|
|
explicit PartialLocalFileLocationPtr(PartialLocalFileLocation location)
|
|
|
|
: location_(make_unique<PartialLocalFileLocation>(location)) {
|
|
|
|
}
|
|
|
|
PartialLocalFileLocationPtr(const PartialLocalFileLocationPtr &other)
|
|
|
|
: location_(make_unique<PartialLocalFileLocation>(*other.location_)) {
|
|
|
|
}
|
|
|
|
PartialLocalFileLocationPtr &operator=(const PartialLocalFileLocationPtr &other) {
|
|
|
|
*location_ = *other.location_;
|
2019-01-02 19:52:44 +01:00
|
|
|
return *this;
|
2019-01-02 19:17:08 +01:00
|
|
|
}
|
|
|
|
PartialLocalFileLocationPtr(PartialLocalFileLocationPtr &&other)
|
|
|
|
: location_(make_unique<PartialLocalFileLocation>(std::move(*other.location_))) {
|
|
|
|
}
|
|
|
|
PartialLocalFileLocationPtr &operator=(PartialLocalFileLocationPtr &&other) {
|
|
|
|
*location_ = std::move(*other.location_);
|
2019-01-02 19:52:44 +01:00
|
|
|
return *this;
|
2019-01-02 19:17:08 +01:00
|
|
|
}
|
|
|
|
~PartialLocalFileLocationPtr() = default;
|
|
|
|
|
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2019-06-19 01:48:34 +02:00
|
|
|
template <class ParserT>
|
|
|
|
void parse(ParserT &parser);
|
2019-01-02 19:17:08 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator==(const PartialLocalFileLocationPtr &lhs, const PartialLocalFileLocationPtr &rhs) {
|
|
|
|
return *lhs.location_ == *rhs.location_;
|
|
|
|
}
|
|
|
|
|
2018-01-20 15:06:22 +01:00
|
|
|
class LocalFileLocation {
|
|
|
|
public:
|
2018-12-31 20:04:05 +01:00
|
|
|
enum class Type : int32 { Empty, Partial, Full };
|
2018-01-20 15:57:52 +01:00
|
|
|
|
|
|
|
Type type() const {
|
2018-01-20 16:16:51 +01:00
|
|
|
return static_cast<Type>(variant_.get_offset());
|
2018-01-20 15:57:52 +01:00
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
PartialLocalFileLocation &partial() {
|
2019-01-02 19:17:08 +01:00
|
|
|
return *variant_.get<1>().location_;
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
FullLocalFileLocation &full() {
|
|
|
|
return variant_.get<2>();
|
|
|
|
}
|
|
|
|
const PartialLocalFileLocation &partial() const {
|
2019-01-02 19:17:08 +01:00
|
|
|
return *variant_.get<1>().location_;
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
const FullLocalFileLocation &full() const {
|
|
|
|
return variant_.get<2>();
|
|
|
|
}
|
|
|
|
|
2018-02-19 23:28:06 +01:00
|
|
|
CSlice file_name() const {
|
|
|
|
switch (type()) {
|
|
|
|
case Type::Partial:
|
|
|
|
return partial().path_;
|
|
|
|
case Type::Full:
|
|
|
|
return full().path_;
|
|
|
|
case Type::Empty:
|
|
|
|
default:
|
|
|
|
return CSlice();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
2018-12-31 20:04:05 +01:00
|
|
|
|
2018-01-20 16:16:51 +01:00
|
|
|
LocalFileLocation() : variant_{EmptyLocalFileLocation()} {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2018-12-05 10:32:31 +01:00
|
|
|
explicit LocalFileLocation(const PartialLocalFileLocation &partial) : variant_(PartialLocalFileLocationPtr(partial)) {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2018-01-20 16:16:51 +01:00
|
|
|
explicit LocalFileLocation(const FullLocalFileLocation &full) : variant_(full) {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
LocalFileLocation(FileType file_type, string path, uint64 mtime_nsec)
|
2018-01-20 16:16:51 +01:00
|
|
|
: variant_(FullLocalFileLocation{file_type, std::move(path), mtime_nsec}) {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2018-01-20 15:17:58 +01:00
|
|
|
|
|
|
|
private:
|
2019-01-02 19:17:08 +01:00
|
|
|
Variant<EmptyLocalFileLocation, PartialLocalFileLocationPtr, FullLocalFileLocation> variant_;
|
2018-01-20 15:17:58 +01:00
|
|
|
|
|
|
|
friend bool operator==(const LocalFileLocation &lhs, const LocalFileLocation &rhs);
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator==(const LocalFileLocation &lhs, const LocalFileLocation &rhs) {
|
|
|
|
return lhs.variant_ == rhs.variant_;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const LocalFileLocation &lhs, const LocalFileLocation &rhs) {
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
2019-01-01 18:02:13 +01:00
|
|
|
inline StringBuilder &operator<<(StringBuilder &sb, const LocalFileLocation &location) {
|
|
|
|
switch (location.type()) {
|
|
|
|
case LocalFileLocation::Type::Empty:
|
|
|
|
return sb << "[empty local location]";
|
|
|
|
case LocalFileLocation::Type::Partial:
|
|
|
|
return sb << location.partial();
|
|
|
|
case LocalFileLocation::Type::Full:
|
|
|
|
return sb << location.full();
|
|
|
|
default:
|
|
|
|
UNREACHABLE();
|
|
|
|
return sb;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
struct FullGenerateFileLocation {
|
2018-01-20 15:57:52 +01:00
|
|
|
FileType file_type_{FileType::None};
|
2018-12-31 20:04:05 +01:00
|
|
|
string original_path_;
|
|
|
|
string conversion_;
|
|
|
|
static const int32 KEY_MAGIC = 0x8b60a1c8;
|
|
|
|
|
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
const FullGenerateFileLocation &as_key() const {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
FullGenerateFileLocation() = default;
|
2018-01-20 15:57:52 +01:00
|
|
|
FullGenerateFileLocation(FileType file_type, string original_path, string conversion)
|
|
|
|
: file_type_(file_type), original_path_(std::move(original_path)), conversion_(std::move(conversion)) {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator<(const FullGenerateFileLocation &lhs, const FullGenerateFileLocation &rhs) {
|
2018-01-20 15:57:52 +01:00
|
|
|
return std::tie(lhs.file_type_, lhs.original_path_, lhs.conversion_) <
|
|
|
|
std::tie(rhs.file_type_, rhs.original_path_, rhs.conversion_);
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator==(const FullGenerateFileLocation &lhs, const FullGenerateFileLocation &rhs) {
|
2018-01-20 15:57:52 +01:00
|
|
|
return std::tie(lhs.file_type_, lhs.original_path_, lhs.conversion_) ==
|
|
|
|
std::tie(rhs.file_type_, rhs.original_path_, rhs.conversion_);
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const FullGenerateFileLocation &lhs, const FullGenerateFileLocation &rhs) {
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline StringBuilder &operator<<(StringBuilder &string_builder,
|
|
|
|
const FullGenerateFileLocation &full_generated_file_location) {
|
2018-11-15 22:25:08 +01:00
|
|
|
return string_builder << '[' << tag("file_type", full_generated_file_location.file_type_)
|
2018-12-31 20:04:05 +01:00
|
|
|
<< tag("original_path", full_generated_file_location.original_path_)
|
2018-11-15 22:25:08 +01:00
|
|
|
<< tag("conversion", full_generated_file_location.conversion_) << ']';
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
|
2018-01-20 15:06:22 +01:00
|
|
|
class GenerateFileLocation {
|
|
|
|
public:
|
2018-12-31 20:04:05 +01:00
|
|
|
enum class Type : int32 { Empty, Full };
|
2018-01-20 15:57:52 +01:00
|
|
|
|
|
|
|
Type type() const {
|
|
|
|
return type_;
|
|
|
|
}
|
2018-01-20 15:06:22 +01:00
|
|
|
|
|
|
|
FullGenerateFileLocation &full() {
|
|
|
|
CHECK(type_ == Type::Full);
|
|
|
|
return full_;
|
|
|
|
}
|
|
|
|
const FullGenerateFileLocation &full() const {
|
|
|
|
CHECK(type_ == Type::Full);
|
|
|
|
return full_;
|
|
|
|
}
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
template <class StorerT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void store(StorerT &storer) const;
|
2018-12-31 20:04:05 +01:00
|
|
|
template <class ParserT>
|
2019-02-07 22:00:26 +01:00
|
|
|
void parse(ParserT &parser);
|
2018-12-31 20:04:05 +01:00
|
|
|
|
|
|
|
GenerateFileLocation() : type_(Type::Empty) {
|
|
|
|
}
|
|
|
|
|
|
|
|
explicit GenerateFileLocation(const FullGenerateFileLocation &full) : type_(Type::Full), full_(full) {
|
|
|
|
}
|
2018-01-20 15:06:22 +01:00
|
|
|
|
2018-12-31 20:04:05 +01:00
|
|
|
GenerateFileLocation(FileType file_type, string original_path, string conversion)
|
2018-01-20 15:06:22 +01:00
|
|
|
: type_(Type::Full), full_{file_type, std::move(original_path), std::move(conversion)} {
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
2018-01-20 15:06:22 +01:00
|
|
|
|
|
|
|
private:
|
2018-01-20 15:57:52 +01:00
|
|
|
Type type_;
|
2018-01-20 15:06:22 +01:00
|
|
|
FullGenerateFileLocation full_;
|
2018-12-31 20:04:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
inline bool operator==(const GenerateFileLocation &lhs, const GenerateFileLocation &rhs) {
|
2018-01-20 15:57:52 +01:00
|
|
|
if (lhs.type() != rhs.type()) {
|
2018-12-31 20:04:05 +01:00
|
|
|
return false;
|
|
|
|
}
|
2018-01-20 15:57:52 +01:00
|
|
|
switch (lhs.type()) {
|
2018-12-31 20:04:05 +01:00
|
|
|
case GenerateFileLocation::Type::Empty:
|
2018-01-20 15:06:22 +01:00
|
|
|
return true;
|
2018-12-31 20:04:05 +01:00
|
|
|
case GenerateFileLocation::Type::Full:
|
2018-01-20 15:06:22 +01:00
|
|
|
return lhs.full() == rhs.full();
|
2018-12-31 20:04:05 +01:00
|
|
|
}
|
|
|
|
UNREACHABLE();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool operator!=(const GenerateFileLocation &lhs, const GenerateFileLocation &rhs) {
|
|
|
|
return !(lhs == rhs);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace td
|