+ extend PyStreambuf to write data

This commit is contained in:
wmayer 2016-06-11 11:54:01 +02:00
parent e42385a25b
commit 432dcb5833
2 changed files with 97 additions and 51 deletions

View File

@ -523,56 +523,99 @@ IODeviceIStreambuf::seekpos(std::streambuf::pos_type pos,
}
// ---------------------------------------------------------
PyStreambuf::PyStreambuf(PyObject* o) : inp(o)
{
setg (buffer+pbSize,
buffer+pbSize,
buffer+pbSize);
}
int PyStreambuf::underflow()
{
if (gptr() < egptr()) {
return *gptr();
}
int numPutback;
numPutback = gptr() - eback();
if (numPutback > pbSize) {
numPutback = pbSize;
}
memcpy (buffer+(pbSize-numPutback), gptr()-numPutback, numPutback);
int num=0;
for (int i=0; i<bufSize; i++) {
char c;
Py::Tuple arg(1);
arg.setItem(0, Py::Int(1));
Py::Callable meth(Py::Object(inp).getAttr("read"));
try {
Py::Char res(meth.apply(arg));
c = static_cast<std::string>(res)[0];
num++;
buffer[pbSize+i] = c;
if (c == '\n')
break;
}
catch (Py::Exception& e) {
e.clear();
if (num == 0)
return EOF;
break;
}
}
setg (buffer+(pbSize-numPutback),
buffer+pbSize,
buffer+pbSize+num);
return *gptr();
}
PyStreambuf::PyStreambuf(PyObject* o) : inp(o)
{
Py_INCREF(inp);
setg (buffer+pbSize,
buffer+pbSize,
buffer+pbSize);
}
PyStreambuf::~PyStreambuf()
{
Py_DECREF(inp);
}
std::streambuf::int_type PyStreambuf::underflow()
{
if (gptr() < egptr()) {
return *gptr();
}
int numPutback;
numPutback = gptr() - eback();
if (numPutback > pbSize) {
numPutback = pbSize;
}
memcpy (buffer+(pbSize-numPutback), gptr()-numPutback, numPutback);
int num=0;
for (int i=0; i<bufSize; i++) {
char c;
Py::Tuple arg(1);
arg.setItem(0, Py::Int(1));
Py::Callable meth(Py::Object(inp).getAttr("read"));
try {
Py::Char res(meth.apply(arg));
c = static_cast<std::string>(res)[0];
num++;
buffer[pbSize+i] = c;
if (c == '\n')
break;
}
catch (Py::Exception& e) {
e.clear();
if (num == 0)
return EOF;
break;
}
}
setg (buffer+(pbSize-numPutback),
buffer+pbSize,
buffer+pbSize+num);
return *gptr();
}
std::streambuf::int_type
PyStreambuf::overflow(std::streambuf::int_type c)
{
if (c != EOF) {
char z = c;
try {
Py::Tuple arg(1);
arg.setItem(0, Py::Char(z));
Py::Callable meth(Py::Object(inp).getAttr("write"));
meth.apply(arg);
}
catch(Py::Exception& e) {
e.clear();
return EOF;
}
}
return c;
}
std::streamsize PyStreambuf::xsputn (const char* s, std::streamsize num)
{
try {
Py::Tuple arg(1);
arg.setItem(0, Py::String(s, num));
Py::Callable meth(Py::Object(inp).getAttr("write"));
meth.apply(arg);
}
catch(Py::Exception& e) {
e.clear();
return 0;
}
return num;
}
// ---------------------------------------------------------

View File

@ -242,9 +242,12 @@ class BaseExport PyStreambuf : public std::streambuf
{
public:
PyStreambuf(PyObject* o);
virtual ~PyStreambuf();
protected:
int underflow();
int_type underflow();
int_type overflow(int_type c = EOF);
std::streamsize xsputn (const char* s, std::streamsize num);
private:
static const int pbSize = 4;