feat(util/serializer): make sure the read/write is portable

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-12-27 18:07:19 -08:00
parent d05695c331
commit 49df0c435d
3 changed files with 45 additions and 13 deletions

View file

@ -77,14 +77,24 @@ deserializer & operator>>(deserializer & d, list<int> & l) {
return d;
}
void display(std::ostringstream const & out) {
std::cout << "OUT: ";
auto str = out.str();
for (auto c : str) {
std::cout << static_cast<int>(static_cast<unsigned char>(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<int> 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<int>(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;

View file

@ -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<unsigned>(m_in.get()) << 24;
r |= static_cast<unsigned>(m_in.get()) << 16;
r |= static_cast<unsigned>(m_in.get()) << 8;
r |= static_cast<unsigned>(m_in.get());
return r;
}
int deserializer_core::read_int() {
return read_unsigned();
}
}

View file

@ -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<char*>(&i), sizeof(i)); }
void write_int(int i) { m_out.write(reinterpret_cast<char*>(&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<char*>(&r), sizeof(r)); return r; }
unsigned read_unsigned() { unsigned r; m_in.read(reinterpret_cast<char*>(&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; }
};