in native/src/seal/serialization.cpp [341:451]
streamoff Serialization::Load(
function<void(istream &, SEALVersion)> load_members, istream &stream, SEAL_MAYBE_UNUSED bool clear_buffers)
{
if (!load_members)
{
throw invalid_argument("load_members is invalid");
}
streamoff in_size = 0;
SEALHeader header;
auto old_except_mask = stream.exceptions();
try
{
// Throw exceptions on ios_base::badbit and ios_base::failbit
stream.exceptions(ios_base::badbit | ios_base::failbit);
// Save the starting position
auto stream_start_pos = stream.tellg();
// First read the header
LoadHeader(stream, header);
if (!IsCompatibleVersion(header))
{
throw logic_error("incompatible version");
}
if (!IsValidHeader(header))
{
throw logic_error("loaded SEALHeader is invalid");
}
// Read header version information so we can call, if necessary, the
// correct variant of load_members.
SEALVersion version{ header.version_major, header.version_minor, 0, 0 };
switch (header.compr_mode)
{
case compr_mode_type::none:
// Read rest of the data
load_members(stream, version);
if (header.size != safe_cast<uint64_t>(stream.tellg() - stream_start_pos))
{
throw logic_error("invalid data size");
}
break;
#ifdef SEAL_USE_ZLIB
case compr_mode_type::zlib:
{
auto compr_size = header.size - safe_cast<uint64_t>(stream.tellg() - stream_start_pos);
// We don't know the decompressed size, but use compr_size as
// starting point for the buffer.
SafeByteBuffer safe_buffer(safe_cast<streamsize>(compr_size), clear_buffers);
iostream temp_stream(&safe_buffer);
temp_stream.exceptions(ios_base::badbit | ios_base::failbit);
auto safe_pool = MemoryManager::GetPool(mm_prof_opt::mm_force_new, clear_buffers);
// Throw an exception on non-zero return value
if (ztools::zlib_inflate_stream(stream, safe_cast<streamoff>(compr_size), temp_stream, safe_pool))
{
throw logic_error("stream decompression failed");
}
load_members(temp_stream, version);
break;
}
#endif
#ifdef SEAL_USE_ZSTD
case compr_mode_type::zstd:
{
auto compr_size = header.size - safe_cast<uint64_t>(stream.tellg() - stream_start_pos);
// We don't know the decompressed size, but use compr_size as
// starting point for the buffer.
SafeByteBuffer safe_buffer(safe_cast<streamsize>(compr_size), clear_buffers);
iostream temp_stream(&safe_buffer);
temp_stream.exceptions(ios_base::badbit | ios_base::failbit);
auto safe_pool = MemoryManager::GetPool(mm_prof_opt::mm_force_new, clear_buffers);
// Throw an exception on non-zero return value
if (ztools::zstd_inflate_stream(stream, safe_cast<streamoff>(compr_size), temp_stream, safe_pool))
{
throw logic_error("stream decompression failed");
}
load_members(temp_stream, version);
break;
}
#endif
default:
throw invalid_argument("unsupported compression mode");
}
in_size = safe_cast<streamoff>(header.size);
}
catch (const ios_base::failure &)
{
stream.exceptions(old_except_mask);
expressive_rethrow_on_ios_base_failure(stream);
}
catch (...)
{
stream.exceptions(old_except_mask);
throw;
}
stream.exceptions(old_except_mask);
return in_size;
}