Add Variant parser and storer.
GitOrigin-RevId: e6b8e46184f67fed50ce96a58a8ba33c17789c57
This commit is contained in:
parent
c72832b462
commit
59fd30237e
@ -53,7 +53,7 @@ struct PhotoSizeSource {
|
||||
// for photos, document thumbnails, encrypted thumbnails
|
||||
struct Thumbnail {
|
||||
Thumbnail() = default;
|
||||
Thumbnail(FileType file_type, int32 thumbnail_type) : thumbnail_type(thumbnail_type) {
|
||||
Thumbnail(FileType file_type, int32 thumbnail_type) : file_type(file_type), thumbnail_type(thumbnail_type) {
|
||||
}
|
||||
|
||||
FileType file_type;
|
||||
|
@ -73,51 +73,12 @@ void PhotoSizeSource::DialogPhoto::parse(ParserT &parser) {
|
||||
|
||||
template <class StorerT>
|
||||
void PhotoSizeSource::store(StorerT &storer) const {
|
||||
using td::store;
|
||||
auto type = get_type();
|
||||
store(type, storer);
|
||||
switch (type) {
|
||||
case Type::Thumbnail:
|
||||
store(thumbnail(), storer);
|
||||
break;
|
||||
case Type::DialogPhoto:
|
||||
store(dialog_photo(), storer);
|
||||
break;
|
||||
case Type::StickerSetThumbnail:
|
||||
store(sticker_set_thumbnail(), storer);
|
||||
break;
|
||||
case Type::Empty:
|
||||
break;
|
||||
}
|
||||
td::store(variant, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void PhotoSizeSource::parse(ParserT &parser) {
|
||||
using td::parse;
|
||||
Type type;
|
||||
parse(type, parser);
|
||||
switch (type) {
|
||||
case Type::Thumbnail: {
|
||||
Thumbnail thumbnail;
|
||||
parse(thumbnail, parser);
|
||||
variant = thumbnail;
|
||||
break;
|
||||
}
|
||||
case Type::DialogPhoto: {
|
||||
DialogPhoto dialog_photo;
|
||||
parse(dialog_photo, parser);
|
||||
variant = dialog_photo;
|
||||
break;
|
||||
}
|
||||
case Type::StickerSetThumbnail: {
|
||||
StickerSetThumbnail sticker_set_thumbnail;
|
||||
parse(sticker_set_thumbnail, parser);
|
||||
variant = sticker_set_thumbnail;
|
||||
break;
|
||||
}
|
||||
case Type::Empty:
|
||||
break;
|
||||
}
|
||||
td::parse(variant, parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
|
@ -744,6 +744,8 @@ struct PartialLocalFileLocationPtr {
|
||||
|
||||
template <class StorerT>
|
||||
void store(StorerT &storer) const;
|
||||
template <class ParserT>
|
||||
void parse(ParserT &parser);
|
||||
};
|
||||
|
||||
inline bool operator==(const PartialLocalFileLocationPtr &lhs, const PartialLocalFileLocationPtr &rhs) {
|
||||
|
@ -42,24 +42,48 @@ void PartialRemoteFileLocation::parse(ParserT &parser) {
|
||||
template <class StorerT>
|
||||
void PhotoRemoteFileLocation::store(StorerT &storer) const {
|
||||
using td::store;
|
||||
bool has_secret = secret_ != 0;
|
||||
bool has_source = source_.get_type() != PhotoSizeSource::Type::Empty;
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(has_secret);
|
||||
STORE_FLAG(has_source);
|
||||
END_STORE_FLAGS();
|
||||
store(id_, storer);
|
||||
store(access_hash_, storer);
|
||||
store(volume_id_, storer);
|
||||
store(secret_, storer);
|
||||
if (has_secret) {
|
||||
store(secret_, storer);
|
||||
}
|
||||
store(local_id_, storer);
|
||||
store(source_, storer);
|
||||
if (has_source) {
|
||||
store(source_, storer);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void PhotoRemoteFileLocation::parse(ParserT &parser) {
|
||||
using td::parse;
|
||||
bool has_secret = true;
|
||||
bool has_source = false;
|
||||
if (parser.version() >= static_cast<int32>(Version::AddPhotoSizeSource)) {
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(has_secret);
|
||||
PARSE_FLAG(has_source);
|
||||
END_PARSE_FLAGS();
|
||||
}
|
||||
parse(id_, parser);
|
||||
parse(access_hash_, parser);
|
||||
parse(volume_id_, parser);
|
||||
parse(secret_, parser);
|
||||
if (has_secret) {
|
||||
parse(secret_, parser);
|
||||
} else {
|
||||
secret_ = 0;
|
||||
}
|
||||
parse(local_id_, parser);
|
||||
if (parser.version() >= static_cast<int32>(Version::AddPhotoSizeSource)) {
|
||||
if (has_source) {
|
||||
parse(source_, parser);
|
||||
} else {
|
||||
source_ = PhotoSizeSource();
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,31 +201,12 @@ void FullRemoteFileLocation::AsKey::store(StorerT &storer) const {
|
||||
|
||||
template <class StorerT>
|
||||
void RemoteFileLocation::store(StorerT &storer) const {
|
||||
storer.store_int(variant_.get_offset());
|
||||
bool ok{false};
|
||||
variant_.visit([&](auto &&value) {
|
||||
using td::store;
|
||||
store(value, storer);
|
||||
ok = true;
|
||||
});
|
||||
CHECK(ok);
|
||||
td::store(variant_, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void RemoteFileLocation::parse(ParserT &parser) {
|
||||
auto type = static_cast<Type>(parser.fetch_int());
|
||||
switch (type) {
|
||||
case Type::Empty:
|
||||
variant_ = EmptyRemoteFileLocation();
|
||||
return;
|
||||
case Type::Partial:
|
||||
variant_ = PartialRemoteFileLocation();
|
||||
return partial().parse(parser);
|
||||
case Type::Full:
|
||||
variant_ = FullRemoteFileLocation();
|
||||
return full().parse(parser);
|
||||
}
|
||||
parser.set_error("Invalid type in RemoteFileLocation");
|
||||
td::parse(variant_, parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
@ -261,32 +266,19 @@ void PartialLocalFileLocationPtr::store(StorerT &storer) const {
|
||||
td::store(*location_, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void PartialLocalFileLocationPtr::parse(ParserT &parser) {
|
||||
td::parse(*location_, parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
void LocalFileLocation::store(StorerT &storer) const {
|
||||
using td::store;
|
||||
store(variant_.get_offset(), storer);
|
||||
variant_.visit([&](auto &&value) {
|
||||
using td::store;
|
||||
store(value, storer);
|
||||
});
|
||||
td::store(variant_, storer);
|
||||
}
|
||||
|
||||
template <class ParserT>
|
||||
void LocalFileLocation::parse(ParserT &parser) {
|
||||
using td::parse;
|
||||
auto type = static_cast<Type>(parser.fetch_int());
|
||||
switch (type) {
|
||||
case Type::Empty:
|
||||
variant_ = EmptyLocalFileLocation();
|
||||
return;
|
||||
case Type::Partial:
|
||||
variant_ = PartialLocalFileLocationPtr();
|
||||
return parse(partial(), parser);
|
||||
case Type::Full:
|
||||
variant_ = FullLocalFileLocation();
|
||||
return parse(full(), parser);
|
||||
}
|
||||
return parser.set_error("Invalid type in LocalFileLocation");
|
||||
td::parse(variant_, parser);
|
||||
}
|
||||
|
||||
template <class StorerT>
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/tl_parsers.h"
|
||||
#include "td/utils/tl_storers.h"
|
||||
#include "td/utils/Variant.h"
|
||||
|
||||
#include <type_traits>
|
||||
#include <unordered_set>
|
||||
@ -186,6 +187,29 @@ std::enable_if_t<!std::is_enum<T>::value> parse(T &val, ParserT &parser) {
|
||||
val.parse(parser);
|
||||
}
|
||||
|
||||
template <class... Types, class StorerT>
|
||||
void store(const Variant<Types...> &variant, StorerT &storer) {
|
||||
store(variant.get_offset(), storer);
|
||||
variant.visit([&storer](auto &&value) {
|
||||
using td::store;
|
||||
store(value, storer);
|
||||
});
|
||||
}
|
||||
template <class... Types, class ParserT>
|
||||
void parse(Variant<Types...> &variant, ParserT &parser) {
|
||||
auto type_offset = parser.fetch_int();
|
||||
if (type_offset < 0 || type_offset >= static_cast<int32>(sizeof...(Types))) {
|
||||
return parser.set_error("Invalid type");
|
||||
}
|
||||
variant.for_each([type_offset, &parser, &variant](int offset, auto *ptr) {
|
||||
using T = std::decay_t<decltype(*ptr)>;
|
||||
if (offset == type_offset) {
|
||||
variant = T();
|
||||
parse(variant.get<T>(), parser);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
template <class T>
|
||||
string serialize(const T &object) {
|
||||
TlStorerCalcLength calc_length;
|
||||
|
Loading…
Reference in New Issue
Block a user