feat(util/serializer): make sure the read/write is portable
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
d05695c331
commit
49df0c435d
3 changed files with 45 additions and 13 deletions
|
@ -77,14 +77,24 @@ deserializer & operator>>(deserializer & d, list<int> & l) {
|
||||||
return d;
|
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() {
|
static void tst1() {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
serializer s(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());
|
std::istringstream in(out.str());
|
||||||
deserializer d(in);
|
deserializer d(in);
|
||||||
lean_assert(d.read_int() == 10);
|
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_bool());
|
||||||
lean_assert(d.read_string() == "hello");
|
lean_assert(d.read_string() == "hello");
|
||||||
lean_assert(d.read_int() == 30);
|
lean_assert(d.read_int() == 30);
|
||||||
|
@ -99,13 +109,7 @@ static void tst2() {
|
||||||
list<int> l3;
|
list<int> l3;
|
||||||
l3 = cons(20, cons(30, l2));
|
l3 = cons(20, cons(30, l2));
|
||||||
s << l1 << l2 << l3 << l2 << l3;
|
s << l1 << l2 << l3 << l2 << l3;
|
||||||
|
display(out);
|
||||||
std::cout << "OUT: ";
|
|
||||||
auto str = out.str();
|
|
||||||
for (auto c : str) {
|
|
||||||
std::cout << static_cast<int>(c) << " ";
|
|
||||||
}
|
|
||||||
std::cout << "\n";
|
|
||||||
|
|
||||||
std::istringstream in(out.str());
|
std::istringstream in(out.str());
|
||||||
deserializer d(in);
|
deserializer d(in);
|
||||||
|
@ -131,6 +135,7 @@ static void tst3() {
|
||||||
name n4(n1, "hello");
|
name n4(n1, "hello");
|
||||||
name n5("simple");
|
name n5("simple");
|
||||||
s << n1 << n2 << n3 << n4 << n2 << n5;
|
s << n1 << n2 << n3 << n4 << n2 << n5;
|
||||||
|
display(out);
|
||||||
std::istringstream in(out.str());
|
std::istringstream in(out.str());
|
||||||
deserializer d(in);
|
deserializer d(in);
|
||||||
name m1, m2, m3, m4, m5, m6;
|
name m1, m2, m3, m4, m5, m6;
|
||||||
|
|
|
@ -8,6 +8,19 @@ Author: Leonardo de Moura
|
||||||
#include "util/serializer.h"
|
#include "util/serializer.h"
|
||||||
|
|
||||||
namespace lean {
|
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 deserializer_core::read_string() {
|
||||||
std::string r;
|
std::string r;
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -18,4 +31,18 @@ std::string deserializer_core::read_string() {
|
||||||
}
|
}
|
||||||
return r;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ public:
|
||||||
serializer_core(std::ostream & out):m_out(out) {}
|
serializer_core(std::ostream & out):m_out(out) {}
|
||||||
void write_string(char const * str) { m_out.write(str, strlen(str) + 1); }
|
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_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_unsigned(unsigned i);
|
||||||
void write_int(int i) { m_out.write(reinterpret_cast<char*>(&i), sizeof(i)); }
|
void write_int(int i);
|
||||||
void write_char(char c) { m_out.put(c); }
|
void write_char(char c) { m_out.put(c); }
|
||||||
void write_bool(bool b) { m_out.put(b ? 1 : 0); }
|
void write_bool(bool b) { m_out.put(b ? 1 : 0); }
|
||||||
};
|
};
|
||||||
|
@ -46,8 +46,8 @@ class deserializer_core {
|
||||||
public:
|
public:
|
||||||
deserializer_core(std::istream & in):m_in(in) {}
|
deserializer_core(std::istream & in):m_in(in) {}
|
||||||
std::string read_string();
|
std::string read_string();
|
||||||
int read_int() { int r; m_in.read(reinterpret_cast<char*>(&r), sizeof(r)); return r; }
|
unsigned read_unsigned();
|
||||||
unsigned read_unsigned() { unsigned r; m_in.read(reinterpret_cast<char*>(&r), sizeof(r)); return r; }
|
int read_int();
|
||||||
char read_char() { return m_in.get(); }
|
char read_char() { return m_in.get(); }
|
||||||
bool read_bool() { return m_in.get() != 0; }
|
bool read_bool() { return m_in.get() != 0; }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue