ObjectSerializer fixes for pr/2086

This commit is contained in:
Andrew Noyes 2019-09-11 13:31:07 -07:00
parent 7ecd31da5a
commit a5314e2cee
2 changed files with 20 additions and 24 deletions

View File

@ -1123,11 +1123,12 @@ void load(Root& root, const uint8_t* in, Context& context) {
} // namespace detail
template <class Context, class FirstMember, class... Members>
uint8_t* save_members(Context& context, FileIdentifier file_identifier, FirstMember& first, Members&... members) {
uint8_t* save_members(Context& context, FileIdentifier file_identifier, const FirstMember& first,
const Members&... members) {
if constexpr (serialize_raw<FirstMember>::value) {
return serialize_raw<FirstMember>::save_raw(context, first);
} else {
const auto& root = detail::fake_root(first, members...);
const auto& root = detail::fake_root(const_cast<FirstMember&>(first), const_cast<Members&>(members)...);
return detail::save(context, root, file_identifier);
}
}

View File

@ -273,23 +273,27 @@ public:
template <class Ar>
void serialize(Ar& ar) {
if(Ar::isDeserializing) {
cache = Standalone<StringRef>();
cacheType = SerializeType::None;
serializer(ar, data);
if constexpr (is_fb_function<Ar>) {
// Suppress vtable collection. Save and load are implemented via the specializations below
} else {
if(cacheType != SerializeType::Binary) {
cache = BinaryWriter::toValue(data, AssumeVersion(currentProtocolVersion));
cacheType = SerializeType::Binary;
if (Ar::isDeserializing) {
cache = Standalone<StringRef>();
cacheType = SerializeType::None;
serializer(ar, data);
} else {
if (cacheType != SerializeType::Binary) {
cache = BinaryWriter::toValue(data, AssumeVersion(currentProtocolVersion));
cacheType = SerializeType::Binary;
}
ar.serializeBytes(const_cast<uint8_t*>(cache.begin()), cache.size());
}
ar.serializeBytes( const_cast<uint8_t *>(cache.begin()), cache.size() );
}
}
private:
T data;
mutable SerializeType cacheType;
mutable Standalone<StringRef> cache;
mutable Standalone<StringRef> cache;
};
// this special case is needed - the code expects
@ -319,25 +323,16 @@ private:
template <class V>
struct serialize_raw<ErrorOr<EnsureTable<CachedSerialization<V>>>> : std::true_type {
template <class Context>
static uint8_t* save_raw(Context& context, const ErrorOr<EnsureTable<CachedSerialization<V>>>& obj) {
auto cache = obj.present() ? obj.get().getCache() : ObjectWriter::toValue(ErrorOr<EnsureTable<V>>(obj.getError()), AssumeVersion(currentProtocolVersion));
static uint8_t* save_raw(Context& context, const ErrorOr<EnsureTable<CachedSerialization<V>>>& obj) {
auto cache = obj.present() ? obj.get().asUnderlyingType().getCache()
: ObjectWriter::toValue(ErrorOr<EnsureTable<V>>(obj.getError()),
AssumeVersion(currentProtocolVersion));
uint8_t* out = context.allocate(cache.size());
memcpy(out, cache.begin(), cache.size());
return out;
}
};
template<class V>
struct scalar_traits<CachedSerialization<V>> : std::true_type {
constexpr static size_t size = 0;
template <class Context>
static void save(uint8_t*, const CachedSerialization<V>&, Context&);
// Context is an arbitrary type that is plumbed by reference throughout
// the load call tree.
template <class Context>
static void load(const uint8_t*, CachedSerialization<V>&, Context& context);
};
template <class T>
struct Callback {
Callback<T> *prev, *next;