77 #include <boost/python/object.hpp> 78 #include <boost/python/str.hpp> 79 #include <boost/python/extract.hpp> 81 #include <boost/optional.hpp> 82 #include <boost/utility/typed_in_place_factory.hpp> 87 namespace ecto {
namespace py {
171 std::ostringstream o;
172 o << file <<
"(" << line <<
")";
176 #define TBXX_ASSERT(condition) \ 177 if (!(condition)) { \ 178 throw std::runtime_error( \ 179 file_and_line_as_string( \ 180 __FILE__, __LINE__) \ 181 + ": ASSERT(" #condition ") failure."); \ 184 #define TBXX_UNREACHABLE_ERROR() \ 185 std::runtime_error( \ 186 "Control flow passes through branch that should be unreachable: " \ 187 + file_and_line_as_string(__FILE__, __LINE__)) 192 typedef std::basic_streambuf<char>
base_t;
219 bp::object& python_file_obj,
220 std::size_t buffer_size_=0)
222 py_read (getattr(python_file_obj,
"read",
bp::object())),
223 py_write(getattr(python_file_obj,
"write",
bp::object())),
224 py_seek (getattr(python_file_obj,
"seek",
bp::object())),
225 py_tell (getattr(python_file_obj,
"tell",
bp::object())),
226 buffer_size(buffer_size_ != 0 ? buffer_size_ : default_buffer_size),
242 catch (bp::error_already_set&) {
265 off_type py_pos = bp::extract<off_type>(
py_tell());
281 int_type
const failure = traits_type::eof();
283 if (status == failure)
return -1;
284 return egptr() - gptr();
289 int_type
const failure = traits_type::eof();
291 throw std::invalid_argument(
292 "That Python file object has no 'read' attribute");
295 char *read_buffer_data;
296 bp::ssize_t py_n_read;
298 &read_buffer_data, &py_n_read) == -1) {
300 throw std::invalid_argument(
301 "The method 'read' of the Python file object " 302 "did not return a string.");
304 off_type n_read = (
off_type)py_n_read;
306 setg(read_buffer_data, read_buffer_data, read_buffer_data + n_read);
308 if (n_read == 0)
return failure;
309 return traits_type::to_int_type(read_buffer_data[0]);
315 throw std::invalid_argument(
316 "That Python file object has no 'write' attribute");
322 if (!traits_type::eq_int_type(c, traits_type::eof())) {
323 py_write(traits_type::to_char_type(c));
328 setp(pbase(), epptr());
332 return traits_type::eq_int_type(
333 c, traits_type::eof()) ? traits_type::not_eof(c) : c;
349 if (traits_type::eq_int_type(status, traits_type::eof())) result = -1;
352 else if (gptr() && gptr() < egptr()) {
366 pos_type
seekoff(off_type off, std::ios_base::seekdir way,
367 std::ios_base::openmode which= std::ios_base::in
368 | std::ios_base::out)
378 throw std::invalid_argument(
379 "That Python file object has no 'seek' attribute");
383 if (which == std::ios_base::in && !gptr()) {
384 if (traits_type::eq_int_type(
underflow(), traits_type::eof())) {
392 case std::ios_base::beg:
395 case std::ios_base::cur:
398 case std::ios_base::end:
410 if (which == std::ios_base::out)
overflow();
411 if (way == std::ios_base::cur) {
412 if (which == std::ios_base::in) off -= egptr() - gptr();
413 else if (which == std::ios_base::out) off += pptr() - pbase();
417 if (which == std::ios_base::in)
underflow();
425 std::ios_base::openmode which= std::ios_base::in
426 | std::ios_base::out)
458 std::ios_base::seekdir way,
459 std::ios_base::openmode which)
461 boost::optional<off_type>
const failure;
464 off_type buf_begin, buf_end, buf_cur, upper_bound;
465 off_type pos_of_buffer_end_in_py_file;
466 if (which == std::ios_base::in) {
468 buf_begin =
reinterpret_cast<std::streamsize
>(eback());
469 buf_cur =
reinterpret_cast<std::streamsize
>(gptr());
470 buf_end =
reinterpret_cast<std::streamsize
>(egptr());
471 upper_bound = buf_end;
473 else if (which == std::ios_base::out) {
475 buf_begin =
reinterpret_cast<std::streamsize
>(pbase());
476 buf_cur =
reinterpret_cast<std::streamsize
>(pptr());
477 buf_end =
reinterpret_cast<std::streamsize
>(epptr());
478 farthest_pptr = std::max(farthest_pptr, pptr());
479 upper_bound =
reinterpret_cast<std::streamsize
>(
farthest_pptr) + 1;
487 if (way == std::ios_base::cur) {
488 buf_sought = buf_cur + off;
490 else if (way == std::ios_base::beg) {
491 buf_sought = buf_end + (off - pos_of_buffer_end_in_py_file);
493 else if (way == std::ios_base::end) {
501 if (buf_sought < buf_begin || buf_sought >= upper_bound)
return failure;
504 if (which == std::ios_base::in) gbump(buf_sought - buf_cur);
505 else if (which == std::ios_base::out) pbump(buf_sought - buf_cur);
506 return pos_of_buffer_end_in_py_file + (buf_sought - buf_end);
516 exceptions(std::ios_base::badbit);
527 exceptions(std::ios_base::badbit);
542 bp::object& python_file_obj,
554 bp::object& python_file_obj,
564 if (this->good()) this->flush();
566 catch (bp::error_already_set&) {
571 "Problem closing python ostream.\n" 572 " Known limitation: the error is unrecoverable. Sorry.\n" 573 " Suggestion for programmer: add ostream.flush() before" 574 " returning.") << std::endl;
582 bp::object& python_file_obj,
bp::object py_read
Definition: streambuf.hpp:433
base_t::char_type char_type
Definition: streambuf.hpp:199
~ostream()
Definition: streambuf.hpp:530
istream(streambuf &buf)
Definition: streambuf.hpp:514
virtual std::streamsize showmanyc()
C.f. C++ standard section 27.5.2.4.3.
Definition: streambuf.hpp:280
base_t::off_type off_type
Definition: streambuf.hpp:202
streambuf python_streambuf
Definition: streambuf.hpp:539
Definition: streambuf.hpp:189
bp::object py_tell
Definition: streambuf.hpp:433
bp::object get_original_file() const
Definition: streambuf.hpp:548
bp::object read_buffer
Definition: streambuf.hpp:442
#define TBXX_UNREACHABLE_ERROR()
Definition: streambuf.hpp:184
bp::object py_write
Definition: streambuf.hpp:433
bp::object file_obj
Definition: streambuf.hpp:532
streambuf_capsule(bp::object &python_file_obj, std::size_t buffer_size=0)
Definition: streambuf.hpp:541
std::size_t buffer_size
Definition: streambuf.hpp:435
virtual int_type underflow()
C.f. C++ standard section 27.5.2.4.3.
Definition: streambuf.hpp:288
std::basic_streambuf< char > base_t
Definition: streambuf.hpp:192
base_t::pos_type pos_type
Definition: streambuf.hpp:201
base_t::traits_type traits_type
Definition: streambuf.hpp:203
Definition: parameters.hpp:11
off_type pos_of_read_buffer_end_in_py_file
Definition: streambuf.hpp:449
virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which=std::ios_base::in|std::ios_base::out)
C.f. C++ standard section 27.5.2.4.2.
Definition: streambuf.hpp:366
ostream(bp::object &python_file_obj, std::size_t buffer_size=0)
Definition: streambuf.hpp:553
Definition: streambuf.hpp:537
Definition: streambuf.hpp:511
streambuf(bp::object &python_file_obj, std::size_t buffer_size_=0)
Construct from a Python file object.
Definition: streambuf.hpp:218
~istream()
Definition: streambuf.hpp:519
Definition: streambuf.hpp:551
base_t::int_type int_type
Definition: streambuf.hpp:200
char * write_buffer
Definition: streambuf.hpp:447
~ostream()
Definition: streambuf.hpp:561
off_type pos_of_write_buffer_end_in_py_file
Definition: streambuf.hpp:449
static std::size_t default_buffer_size
The default size of the read and write buffer.
Definition: streambuf.hpp:213
ostream(streambuf &buf)
Definition: streambuf.hpp:525
virtual int_type overflow(int_type c=traits_type_eof())
C.f. C++ standard section 27.5.2.4.5.
Definition: streambuf.hpp:313
virtual int sync()
Update the python file to reflect the state of this stream buffer.
Definition: streambuf.hpp:343
Definition: streambuf.hpp:522
char * farthest_pptr
Definition: streambuf.hpp:453
boost::optional< off_type > seekoff_without_calling_python(off_type off, std::ios_base::seekdir way, std::ios_base::openmode which)
Definition: streambuf.hpp:456
Definition: streambuf.hpp:579
istream(bp::object &python_file_obj, std::size_t buffer_size=0)
Definition: streambuf.hpp:581
bp::object py_seek
Definition: streambuf.hpp:433
std::string file_and_line_as_string(const char *file, long line)
A stream buffer getting data from and putting data into a Python file object.
Definition: streambuf.hpp:167
static int traits_type_eof()
Definition: streambuf.hpp:207
Definition: std_map_indexing_suite.hpp:20
#define TBXX_ASSERT(condition)
Definition: streambuf.hpp:176
virtual ~streambuf()
Mundane destructor freeing the allocated resources.
Definition: streambuf.hpp:272
virtual pos_type seekpos(pos_type sp, std::ios_base::openmode which=std::ios_base::in|std::ios_base::out)
C.f. C++ standard section 27.5.2.4.2.
Definition: streambuf.hpp:424