+ prepare PyStreambuf for buffered writing

This commit is contained in:
wmayer 2016-06-12 18:20:31 +02:00
parent 0d4be03f4b
commit c3318a3fff
2 changed files with 57 additions and 4 deletions

View File

@ -524,6 +524,9 @@ IODeviceIStreambuf::seekpos(std::streambuf::pos_type pos,
// ---------------------------------------------------------
// Buffering would make it very fast but it doesn't seem to write all data
//#define PYSTREAM_BUFFERED
// http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
PyStreambuf::PyStreambuf(PyObject* o, std::size_t buf_size, std::size_t put_back)
: inp(o)
@ -533,6 +536,10 @@ PyStreambuf::PyStreambuf(PyObject* o, std::size_t buf_size, std::size_t put_back
Py_INCREF(inp);
char *end = &buffer.front() + buffer.size();
setg(end, end, end);
#ifdef PYSTREAM_BUFFERED
char *base = &buffer.front();
setp(base, base + buffer.size() - 1);
#endif
}
PyStreambuf::~PyStreambuf()
@ -580,10 +587,20 @@ std::streambuf::int_type PyStreambuf::underflow()
}
std::streambuf::int_type
PyStreambuf::overflow(std::streambuf::int_type c)
PyStreambuf::overflow(std::streambuf::int_type ch)
{
if (c != EOF) {
char z = c;
#ifdef PYSTREAM_BUFFERED
if (ch != traits_type::eof()) {
*pptr() = ch;
pbump(1);
if (flushBuffer())
return ch;
}
return traits_type::eof();
#else
if (ch != EOF) {
char z = ch;
try {
Py::Tuple arg(1);
@ -597,11 +614,42 @@ PyStreambuf::overflow(std::streambuf::int_type c)
}
}
return c;
return ch;
#endif
}
int PyStreambuf::sync()
{
#ifdef PYSTREAM_BUFFERED
return flushBuffer() ? 0 : -1;
#else
return std::streambuf::sync();
#endif
}
bool PyStreambuf::flushBuffer()
{
std::ptrdiff_t n = pptr() - pbase();
pbump(-n);
try {
Py::Tuple arg(1);
arg.setItem(0, Py::String(pbase(), n));
Py::Callable meth(Py::Object(inp).getAttr("write"));
meth.apply(arg);
return true;
}
catch(Py::Exception& e) {
e.clear();
return false;
}
}
std::streamsize PyStreambuf::xsputn (const char* s, std::streamsize num)
{
#ifdef PYSTREAM_BUFFERED
return std::streambuf::xsputn(s, num);
#else
try {
Py::Tuple arg(1);
arg.setItem(0, Py::String(s, num));
@ -614,6 +662,7 @@ std::streamsize PyStreambuf::xsputn (const char* s, std::streamsize num)
}
return num;
#endif
}
// ---------------------------------------------------------

View File

@ -248,6 +248,10 @@ protected:
int_type underflow();
int_type overflow(int_type c = EOF);
std::streamsize xsputn (const char* s, std::streamsize num);
int sync();
private:
bool flushBuffer();
private:
PyObject* inp;