From e487633bc664b9943c578539c068d558f507e901 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 14 Jun 2016 13:59:02 +0200 Subject: [PATCH] + support of seek operation on PyStreambuf --- src/Base/Stream.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++--- src/Base/Stream.h | 8 ++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/Base/Stream.cpp b/src/Base/Stream.cpp index f3583d03f..121fe507d 100644 --- a/src/Base/Stream.cpp +++ b/src/Base/Stream.cpp @@ -548,7 +548,7 @@ PyStreambuf::~PyStreambuf() Py_DECREF(inp); } -std::streambuf::int_type PyStreambuf::underflow() +PyStreambuf::int_type PyStreambuf::underflow() { if (gptr() < egptr()) { return traits_type::to_int_type(*gptr()); @@ -587,8 +587,8 @@ std::streambuf::int_type PyStreambuf::underflow() return traits_type::to_int_type(*gptr()); } -std::streambuf::int_type -PyStreambuf::overflow(std::streambuf::int_type ch) +PyStreambuf::int_type +PyStreambuf::overflow(PyStreambuf::int_type ch) { #ifdef PYSTREAM_BUFFERED sync(); @@ -669,6 +669,50 @@ std::streamsize PyStreambuf::xsputn (const char* s, std::streamsize num) #endif } +PyStreambuf::pos_type +PyStreambuf::seekoff(PyStreambuf::off_type offset, PyStreambuf::seekdir dir, PyStreambuf::openmode /*mode*/) +{ + int whence = 0; + switch (dir) { + case std::ios_base::beg: + whence = 0; + break; + case std::ios_base::cur: + whence = 1; + break; + case std::ios_base::end: + whence = 2; + break; + default: + return pos_type(off_type(-1)); + } + + try { + Py::Tuple arg(2); + arg.setItem(0, Py::Long(static_cast(offset))); + arg.setItem(1, Py::Long(whence)); + Py::Callable seek(Py::Object(inp).getAttr("seek")); + seek.apply(arg); + + // get current position + Py::Tuple arg2; + Py::Callable tell(Py::Object(inp).getAttr("tell")); + Py::Long pos(tell.apply(arg2)); + long cur_pos = static_cast(pos); + return static_cast(cur_pos); + } + catch(Py::Exception& e) { + e.clear(); + return pos_type(off_type(-1)); + } +} + +PyStreambuf::pos_type +PyStreambuf::seekpos(PyStreambuf::pos_type offset, PyStreambuf::openmode mode) +{ + return seekoff(offset, std::ios::beg, mode); +} + // --------------------------------------------------------- Streambuf::Streambuf(const std::string& data) diff --git a/src/Base/Stream.h b/src/Base/Stream.h index 0282a5557..4312f32e1 100644 --- a/src/Base/Stream.h +++ b/src/Base/Stream.h @@ -240,6 +240,12 @@ protected: class BaseExport PyStreambuf : public std::streambuf { + typedef std::streambuf::int_type int_type; + typedef std::streambuf::pos_type pos_type; + typedef std::streambuf::off_type off_type; + typedef std::ios::seekdir seekdir; + typedef std::ios::openmode openmode; + public: PyStreambuf(PyObject* o, std::size_t buf_size = 256, std::size_t put_back = 8); virtual ~PyStreambuf(); @@ -249,6 +255,8 @@ protected: int_type overflow(int_type c = EOF); std::streamsize xsputn (const char* s, std::streamsize num); int sync(); + pos_type seekoff(off_type offset, seekdir dir, openmode); + pos_type seekpos(pos_type offset, openmode mode); private: bool flushBuffer();