11#ifndef _G3_SERIALIZATION_H
22#define _G3_SERIALIZATION_H
33
4- #include < dataio.h >
4+ #include < sstream >
55
66#include < cereal/archives/portable_binary.hpp>
77
@@ -22,15 +22,76 @@ template void x::serialize(cereal::PortableBinaryInputArchive &, unsigned); \
2222template void x::save (cereal::PortableBinaryOutputArchive &, unsigned ) const ; \
2323template void x::load (cereal::PortableBinaryInputArchive &, unsigned ); \
2424
25+ // Work around crummy slow implementation of xsgetn() in libc++
26+ class G3InputStreamBuffer : public std ::basic_streambuf<char >
27+ {
28+ public:
29+ G3InputStreamBuffer (std::vector<char > &vec) : basic_streambuf() {
30+ setg (&vec[0 ], &vec[0 ], &vec[0 ] + vec.size ());
31+ }
32+ G3InputStreamBuffer (char *buf, size_t len) : basic_streambuf() {
33+ setg (buf, buf, buf + len);
34+ }
35+ protected:
36+ std::streamsize xsgetn (char_type *buf, std::streamsize n) {
37+ std::streamsize to_read = egptr () - gptr ();
38+ if (to_read > n)
39+ to_read = n;
40+ memcpy (buf, gptr (), to_read);
41+ gbump (to_read);
42+ return to_read;
43+ }
44+ };
45+
46+ class G3BufferInputStream : public std ::istream
47+ {
48+ public:
49+ G3BufferInputStream (std::vector<char > &vec) : std::istream(&sbuf_), sbuf_(vec) {}
50+ G3BufferInputStream (char *buf, size_t len) : std::istream(&sbuf_), sbuf_(buf, len) {}
51+ private:
52+ G3InputStreamBuffer sbuf_;
53+ };
54+
55+ class G3OutputStreamBuffer : public std ::basic_streambuf<char >
56+ {
57+ public:
58+ G3OutputStreamBuffer (std::vector<char > &buffer) : buffer_(buffer) {
59+ setp (&buffer_[0 ], &buffer_[0 ] + buffer_.size ());
60+ }
61+ protected:
62+ std::streamsize xsputn (const char * s, std::streamsize n) {
63+ buffer_.insert (buffer_.end (), s, s + n);
64+ pbump (n);
65+ return n;
66+ }
67+
68+ int overflow (int c = std::char_traits<char >::eof()) {
69+ if (c != std::char_traits<char >::eof ()) {
70+ buffer_.push_back (static_cast <char >(c));
71+ pbump (1 );
72+ }
73+ return c;
74+ }
75+ private:
76+ std::vector<char >& buffer_;
77+ };
78+
79+ class G3BufferOutputStream : public std ::ostream
80+ {
81+ public:
82+ G3BufferOutputStream (std::vector<char > &vec) : std::ostream(&sbuf_), sbuf_(vec) {}
83+ private:
84+ G3OutputStreamBuffer sbuf_;
85+ };
86+
2587template <class T >
2688struct g3frameobject_picklesuite : boost::python::pickle_suite
2789{
2890 static boost::python::tuple getstate (boost::python::object obj)
2991 {
3092 namespace bp = boost::python;
3193 std::vector<char > buffer;
32- g3_ostream os;
33- g3_ostream_to_buffer (os, buffer);
94+ G3BufferOutputStream os (buffer);
3495 {
3596 cereal::PortableBinaryOutputArchive ar (os);
3697 ar << bp::extract<const T &>(obj)();
@@ -50,8 +111,7 @@ struct g3frameobject_picklesuite : boost::python::pickle_suite
50111 PyObject_GetBuffer (bp::object (state[1 ]).ptr (), &view,
51112 PyBUF_SIMPLE);
52113
53- g3_istream fis;
54- g3_istream_from_buffer (fis, (char *)view.buf , view.len );
114+ G3BufferInputStream fis ((char *)view.buf , view.len );
55115 cereal::PortableBinaryInputArchive ar (fis);
56116
57117 bp::extract<bp::dict>(obj.attr (" __dict__" ))().update (state[0 ]);
0 commit comments