Add Variant parser and storer.

GitOrigin-RevId: e6b8e46184f67fed50ce96a58a8ba33c17789c57
This commit is contained in:
levlam 2019-06-19 02:48:34 +03:00
parent c72832b462
commit 59fd30237e
5 changed files with 66 additions and 87 deletions

View File

@ -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;

View File

@ -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>

View File

@ -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) {

View File

@ -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>

View File

@ -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;