From 49df0c435dd1eaaf121db2ecdfe8f9c7c4e05f7c Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Fri, 27 Dec 2013 18:07:19 -0800 Subject: [PATCH] feat(util/serializer): make sure the read/write is portable Signed-off-by: Leonardo de Moura --- src/tests/util/serializer.cpp | 23 ++++++++++++++--------- src/util/serializer.cpp | 27 +++++++++++++++++++++++++++ src/util/serializer.h | 8 ++++---- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/tests/util/serializer.cpp b/src/tests/util/serializer.cpp index e3fe0c182..ffe169623 100644 --- a/src/tests/util/serializer.cpp +++ b/src/tests/util/serializer.cpp @@ -77,14 +77,24 @@ deserializer & operator>>(deserializer & d, list & l) { return d; } +void display(std::ostringstream const & out) { + std::cout << "OUT: "; + auto str = out.str(); + for (auto c : str) { + std::cout << static_cast(static_cast(c)) << " "; + } + std::cout << "\n"; +} + static void tst1() { std::ostringstream out; serializer s(out); - s.write_int(10); s.write_int(20); s.write_bool(false); s.write_string("hello"); s.write_int(30); + s.write_int(10); s.write_int(-20); s.write_bool(false); s.write_string("hello"); s.write_int(30); + display(out); std::istringstream in(out.str()); deserializer d(in); lean_assert(d.read_int() == 10); - lean_assert(d.read_int() == 20); + lean_assert(d.read_int() == -20); lean_assert(!d.read_bool()); lean_assert(d.read_string() == "hello"); lean_assert(d.read_int() == 30); @@ -99,13 +109,7 @@ static void tst2() { list l3; l3 = cons(20, cons(30, l2)); s << l1 << l2 << l3 << l2 << l3; - - std::cout << "OUT: "; - auto str = out.str(); - for (auto c : str) { - std::cout << static_cast(c) << " "; - } - std::cout << "\n"; + display(out); std::istringstream in(out.str()); deserializer d(in); @@ -131,6 +135,7 @@ static void tst3() { name n4(n1, "hello"); name n5("simple"); s << n1 << n2 << n3 << n4 << n2 << n5; + display(out); std::istringstream in(out.str()); deserializer d(in); name m1, m2, m3, m4, m5, m6; diff --git a/src/util/serializer.cpp b/src/util/serializer.cpp index e22099ed3..657ff6e64 100644 --- a/src/util/serializer.cpp +++ b/src/util/serializer.cpp @@ -8,6 +8,19 @@ Author: Leonardo de Moura #include "util/serializer.h" namespace lean { +void serializer_core::write_unsigned(unsigned i) { + static_assert(sizeof(i) == 4, "unexpected unsigned size"); + m_out.put((i >> 24) & 0xff); + m_out.put((i >> 16) & 0xff); + m_out.put((i >> 8) & 0xff); + m_out.put(i & 0xff); +} + +void serializer_core::write_int(int i) { + static_assert(sizeof(i) == 4, "unexpected int size"); + write_unsigned(i); +} + std::string deserializer_core::read_string() { std::string r; while (true) { @@ -18,4 +31,18 @@ std::string deserializer_core::read_string() { } return r; } + +unsigned deserializer_core::read_unsigned() { + unsigned r; + static_assert(sizeof(r) == 4, "unexpected unsigned size"); + r = static_cast(m_in.get()) << 24; + r |= static_cast(m_in.get()) << 16; + r |= static_cast(m_in.get()) << 8; + r |= static_cast(m_in.get()); + return r; +} + +int deserializer_core::read_int() { + return read_unsigned(); +} } diff --git a/src/util/serializer.h b/src/util/serializer.h index 4d0833278..25107cd63 100644 --- a/src/util/serializer.h +++ b/src/util/serializer.h @@ -22,8 +22,8 @@ public: serializer_core(std::ostream & out):m_out(out) {} void write_string(char const * str) { m_out.write(str, strlen(str) + 1); } void write_string(std::string const & str) { m_out.write(str.c_str(), str.size() + 1); } - void write_unsigned(unsigned i) { m_out.write(reinterpret_cast(&i), sizeof(i)); } - void write_int(int i) { m_out.write(reinterpret_cast(&i), sizeof(i)); } + void write_unsigned(unsigned 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); } }; @@ -46,8 +46,8 @@ class deserializer_core { public: deserializer_core(std::istream & in):m_in(in) {} std::string read_string(); - int read_int() { int r; m_in.read(reinterpret_cast(&r), sizeof(r)); return r; } - unsigned read_unsigned() { unsigned r; m_in.read(reinterpret_cast(&r), sizeof(r)); return r; } + unsigned read_unsigned(); + int read_int(); char read_char() { return m_in.get(); } bool read_bool() { return m_in.get() != 0; } };