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
|
// for photos, document thumbnails, encrypted thumbnails
|
||||||
struct Thumbnail {
|
struct Thumbnail {
|
||||||
Thumbnail() = default;
|
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;
|
FileType file_type;
|
||||||
|
@ -73,51 +73,12 @@ void PhotoSizeSource::DialogPhoto::parse(ParserT &parser) {
|
|||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
void PhotoSizeSource::store(StorerT &storer) const {
|
void PhotoSizeSource::store(StorerT &storer) const {
|
||||||
using td::store;
|
td::store(variant, storer);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
void PhotoSizeSource::parse(ParserT &parser) {
|
void PhotoSizeSource::parse(ParserT &parser) {
|
||||||
using td::parse;
|
td::parse(variant, parser);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
|
@ -744,6 +744,8 @@ struct PartialLocalFileLocationPtr {
|
|||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
void store(StorerT &storer) const;
|
void store(StorerT &storer) const;
|
||||||
|
template <class ParserT>
|
||||||
|
void parse(ParserT &parser);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const PartialLocalFileLocationPtr &lhs, const PartialLocalFileLocationPtr &rhs) {
|
inline bool operator==(const PartialLocalFileLocationPtr &lhs, const PartialLocalFileLocationPtr &rhs) {
|
||||||
|
@ -42,24 +42,48 @@ void PartialRemoteFileLocation::parse(ParserT &parser) {
|
|||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
void PhotoRemoteFileLocation::store(StorerT &storer) const {
|
void PhotoRemoteFileLocation::store(StorerT &storer) const {
|
||||||
using td::store;
|
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(id_, storer);
|
||||||
store(access_hash_, storer);
|
store(access_hash_, storer);
|
||||||
store(volume_id_, storer);
|
store(volume_id_, storer);
|
||||||
|
if (has_secret) {
|
||||||
store(secret_, storer);
|
store(secret_, storer);
|
||||||
|
}
|
||||||
store(local_id_, storer);
|
store(local_id_, storer);
|
||||||
|
if (has_source) {
|
||||||
store(source_, storer);
|
store(source_, storer);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
void PhotoRemoteFileLocation::parse(ParserT &parser) {
|
void PhotoRemoteFileLocation::parse(ParserT &parser) {
|
||||||
using td::parse;
|
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(id_, parser);
|
||||||
parse(access_hash_, parser);
|
parse(access_hash_, parser);
|
||||||
parse(volume_id_, parser);
|
parse(volume_id_, parser);
|
||||||
|
if (has_secret) {
|
||||||
parse(secret_, parser);
|
parse(secret_, parser);
|
||||||
|
} else {
|
||||||
|
secret_ = 0;
|
||||||
|
}
|
||||||
parse(local_id_, parser);
|
parse(local_id_, parser);
|
||||||
if (parser.version() >= static_cast<int32>(Version::AddPhotoSizeSource)) {
|
if (has_source) {
|
||||||
parse(source_, parser);
|
parse(source_, parser);
|
||||||
|
} else {
|
||||||
|
source_ = PhotoSizeSource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,31 +201,12 @@ void FullRemoteFileLocation::AsKey::store(StorerT &storer) const {
|
|||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
void RemoteFileLocation::store(StorerT &storer) const {
|
void RemoteFileLocation::store(StorerT &storer) const {
|
||||||
storer.store_int(variant_.get_offset());
|
td::store(variant_, storer);
|
||||||
bool ok{false};
|
|
||||||
variant_.visit([&](auto &&value) {
|
|
||||||
using td::store;
|
|
||||||
store(value, storer);
|
|
||||||
ok = true;
|
|
||||||
});
|
|
||||||
CHECK(ok);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
void RemoteFileLocation::parse(ParserT &parser) {
|
void RemoteFileLocation::parse(ParserT &parser) {
|
||||||
auto type = static_cast<Type>(parser.fetch_int());
|
td::parse(variant_, parser);
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
@ -261,32 +266,19 @@ void PartialLocalFileLocationPtr::store(StorerT &storer) const {
|
|||||||
td::store(*location_, storer);
|
td::store(*location_, storer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class ParserT>
|
||||||
|
void PartialLocalFileLocationPtr::parse(ParserT &parser) {
|
||||||
|
td::parse(*location_, parser);
|
||||||
|
}
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
void LocalFileLocation::store(StorerT &storer) const {
|
void LocalFileLocation::store(StorerT &storer) const {
|
||||||
using td::store;
|
td::store(variant_, storer);
|
||||||
store(variant_.get_offset(), storer);
|
|
||||||
variant_.visit([&](auto &&value) {
|
|
||||||
using td::store;
|
|
||||||
store(value, storer);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ParserT>
|
template <class ParserT>
|
||||||
void LocalFileLocation::parse(ParserT &parser) {
|
void LocalFileLocation::parse(ParserT &parser) {
|
||||||
using td::parse;
|
td::parse(variant_, parser);
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class StorerT>
|
template <class StorerT>
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
#include "td/utils/tl_parsers.h"
|
#include "td/utils/tl_parsers.h"
|
||||||
#include "td/utils/tl_storers.h"
|
#include "td/utils/tl_storers.h"
|
||||||
|
#include "td/utils/Variant.h"
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
@ -186,6 +187,29 @@ std::enable_if_t<!std::is_enum<T>::value> parse(T &val, ParserT &parser) {
|
|||||||
val.parse(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>
|
template <class T>
|
||||||
string serialize(const T &object) {
|
string serialize(const T &object) {
|
||||||
TlStorerCalcLength calc_length;
|
TlStorerCalcLength calc_length;
|
||||||
|
Loading…
Reference in New Issue
Block a user