/* Copyright (c) 2013 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Author: Leonardo de Moura */ #pragma once #include #include #include #include #include #include #include #include "runtime/int64.h" #include "runtime/optional.h" namespace lean { struct object; class mpz; class serializer { std::ostream & m_out; std::unordered_map, std::equal_to> m_obj_table; void write_constructor(object * o); void write_closure(object * o); void write_thunk(object * o); void write_task(object * o); void write_array(object * o); void write_scalar_array(object * o); void write_string_object(object * o); void write_external(object * o); public: serializer(std::ostream & out):m_out(out) {} ~serializer(); void write_string(char const * str) { m_out.write(str, strlen(str) + 1); } void write_string(std::string const & str) { write_string(str.c_str()); } void write_unsigned_short(unsigned short i); void write_unsigned(unsigned i); void write_uint64(uint64 i); void write_size_t(size_t i); void write_int(int i); void write_char(char c) { m_out.put(c); } void write_bool(bool b) { m_out.put(b ? 1 : 0); } void write_double(double b); void write_mpz(mpz const & m); void write_object(object * o); void write_blob(std::string const &); }; inline serializer & operator<<(serializer & s, char const * str) { s.write_string(str); return s; } inline serializer & operator<<(serializer & s, std::string const & str) { s.write_string(str); return s; } inline serializer & operator<<(serializer & s, unsigned i) { s.write_unsigned(i); return s; } inline serializer & operator<<(serializer & s, uint64 i) { s.write_uint64(i); return s; } inline serializer & operator<<(serializer & s, int i) { s.write_int(i); return s; } inline serializer & operator<<(serializer & s, char c) { s.write_char(c); return s; } inline serializer & operator<<(serializer & s, bool b) { s.write_bool(b); return s; } inline serializer & operator<<(serializer & s, double b) { s.write_double(b); return s; } inline serializer & operator<<(serializer & s, object * o) { s.write_object(o); return s; } class deserializer { std::istream & m_in; std::vector m_objs; optional m_fname; unsigned read_unsigned_ext(); object * read_constructor(); object * read_closure(); object * read_thunk(); object * read_task(); object * read_array(); object * read_scalar_array(); object * read_string_object(); object * read_external(); public: deserializer(std::istream & in):m_in(in) {} deserializer(std::istream & in, optional const & fname):m_in(in), m_fname(fname) {} ~deserializer(); std::string read_string(); unsigned read_unsigned() { unsigned r = static_cast(m_in.get()); return r < 255 ? r : read_unsigned_ext(); } uint64 read_uint64(); size_t read_size_t(); int read_int() { return read_unsigned(); } char read_char() { return m_in.get(); } bool read_bool() { return m_in.get() != 0; } unsigned short read_unsigned_short(); double read_double(); mpz read_mpz(); std::string read_blob(); object * read_object(); optional get_fname() const { return m_fname; } }; inline deserializer & operator>>(deserializer & d, std::string & str) { str = d.read_string(); return d; } inline deserializer & operator>>(deserializer & d, unsigned & i) { i = d.read_unsigned(); return d; } inline deserializer & operator>>(deserializer & d, uint64 & i) { i = d.read_uint64(); return d; } inline deserializer & operator>>(deserializer & d, int & i) { i = d.read_int(); return d; } inline deserializer & operator>>(deserializer & d, char & c) { c = d.read_char(); return d; } inline deserializer & operator>>(deserializer & d, bool & b) { b = d.read_bool(); return d; } inline deserializer & operator>>(deserializer & d, double & b) { b = d.read_double(); return d; } class corrupted_stream_exception : public exception { public: corrupted_stream_exception(); }; void initialize_serializer(); void finalize_serializer(); template serializer & write_optional(serializer & s, optional const & a) { if (a) s << true << *a; else s << false; return s; } template optional read_optional(deserializer & d) { if (d.read_bool()) { T r; d >> r; return optional(r); } else { return optional(); } } template serializer & operator<<(serializer & s, optional const & a) { return write_optional(s, a); } template deserializer & operator>>(deserializer & d, optional & a) { a = read_optional(d); return d; } }