mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
finish removing boost python dependency, looking promising!
This commit is contained in:
parent
588809d74d
commit
dbe60a5227
|
@ -6,6 +6,7 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
namespace xlnt {
|
namespace xlnt {
|
||||||
namespace arrow {
|
namespace arrow {
|
||||||
|
@ -116,10 +117,10 @@ class streambuf : public std::basic_streambuf<char>
|
||||||
PyObject *python_file_obj,
|
PyObject *python_file_obj,
|
||||||
std::size_t buffer_size_ = 0)
|
std::size_t buffer_size_ = 0)
|
||||||
:
|
:
|
||||||
py_read (PyObject_GetAttr(python_file_obj, "read")),
|
py_read (PyObject_GetAttrString(python_file_obj, "read")),
|
||||||
py_write(PyObject_GetAttr(python_file_obj, "write")),
|
py_write(PyObject_GetAttrString(python_file_obj, "write")),
|
||||||
py_seek (PyObject_GetAttr(python_file_obj, "seek")),
|
py_seek (PyObject_GetAttrString(python_file_obj, "seek")),
|
||||||
py_tell (PyObject_GetAttr(python_file_obj, "tell")),
|
py_tell (PyObject_GetAttrString(python_file_obj, "tell")),
|
||||||
buffer_size(buffer_size_ != 0 ? buffer_size_ : default_buffer_size),
|
buffer_size(buffer_size_ != 0 ? buffer_size_ : default_buffer_size),
|
||||||
write_buffer(0),
|
write_buffer(0),
|
||||||
pos_of_read_buffer_end_in_py_file(0),
|
pos_of_read_buffer_end_in_py_file(0),
|
||||||
|
@ -132,17 +133,13 @@ class streambuf : public std::basic_streambuf<char>
|
||||||
py_tell and py_seek.
|
py_tell and py_seek.
|
||||||
*/
|
*/
|
||||||
if (py_tell != nullptr) {
|
if (py_tell != nullptr) {
|
||||||
try {
|
|
||||||
PyObject_CallFunction(py_tell, nullptr);
|
PyObject_CallFunction(py_tell, nullptr);
|
||||||
}
|
if (PyErr_Occurred() != nullptr)
|
||||||
catch (bp::error_already_set&) {
|
{
|
||||||
py_tell = nullptr;
|
py_tell = nullptr;
|
||||||
py_seek = nullptr;
|
py_seek = nullptr;
|
||||||
/* Boost.Python does not do any Python exception handling whatsoever
|
PyErr_Clear();
|
||||||
So we need to catch it by hand like so.
|
}
|
||||||
*/
|
|
||||||
PyErr_Clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (py_write != nullptr) {
|
if (py_write != nullptr) {
|
||||||
|
@ -157,8 +154,8 @@ class streambuf : public std::basic_streambuf<char>
|
||||||
setp(0, 0);
|
setp(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (py_tell != nulllptr) {
|
if (py_tell != nullptr) {
|
||||||
auto py_pos = static_cast<off_type>(PyLong_AsLong(PyObject_CallFunction(py_tell, nullptr)));
|
auto py_pos = extract_int<off_type>(PyObject_CallFunction(py_tell, nullptr));
|
||||||
pos_of_read_buffer_end_in_py_file = py_pos;
|
pos_of_read_buffer_end_in_py_file = py_pos;
|
||||||
pos_of_write_buffer_end_in_py_file = py_pos;
|
pos_of_write_buffer_end_in_py_file = py_pos;
|
||||||
}
|
}
|
||||||
|
@ -188,16 +185,15 @@ class streambuf : public std::basic_streambuf<char>
|
||||||
"That Python file object has no 'read' attribute");
|
"That Python file object has no 'read' attribute");
|
||||||
}
|
}
|
||||||
read_buffer = PyObject_CallFunction(py_read, "i", buffer_size);
|
read_buffer = PyObject_CallFunction(py_read, "i", buffer_size);
|
||||||
char *read_buffer_data;
|
char *read_buffer_data = nullptr;
|
||||||
bp::ssize_t py_n_read;
|
Py_ssize_t py_n_read = 0;
|
||||||
if (PyBytes_AsStringAndSize(read_buffer.ptr(),
|
if (PyBytes_AsStringAndSize(read_buffer, &read_buffer_data, &py_n_read) == -1) {
|
||||||
&read_buffer_data, &py_n_read) == -1) {
|
|
||||||
setg(0, 0, 0);
|
setg(0, 0, 0);
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(
|
||||||
"The method 'read' of the Python file object "
|
"The method 'read' of the Python file object "
|
||||||
"did not return a string.");
|
"did not return a string.");
|
||||||
}
|
}
|
||||||
off_type n_read = (off_type)py_n_read;
|
auto n_read = (off_type)py_n_read;
|
||||||
pos_of_read_buffer_end_in_py_file += n_read;
|
pos_of_read_buffer_end_in_py_file += n_read;
|
||||||
setg(read_buffer_data, read_buffer_data, read_buffer_data + n_read);
|
setg(read_buffer_data, read_buffer_data, read_buffer_data + n_read);
|
||||||
// ^^^27.5.2.3.1 (4)
|
// ^^^27.5.2.3.1 (4)
|
||||||
|
@ -212,11 +208,12 @@ class streambuf : public std::basic_streambuf<char>
|
||||||
"That Python file object has no 'write' attribute");
|
"That Python file object has no 'write' attribute");
|
||||||
}
|
}
|
||||||
farthest_pptr = std::max(farthest_pptr, pptr());
|
farthest_pptr = std::max(farthest_pptr, pptr());
|
||||||
off_type n_written = (off_type)(farthest_pptr - pbase());
|
auto n_written = (off_type)(farthest_pptr - pbase());
|
||||||
bp::str chunk(pbase(), farthest_pptr);
|
auto chunk = PyBytes_FromStringAndSize(pbase(), farthest_pptr - pbase());
|
||||||
py_write(chunk);
|
PyObject_CallFunction(py_write, "O", chunk);
|
||||||
if (!traits_type::eq_int_type(c, traits_type::eof())) {
|
if (!traits_type::eq_int_type(c, traits_type::eof())) {
|
||||||
py_write(traits_type::to_char_type(c));
|
auto ch = traits_type::to_char_type(c);
|
||||||
|
PyObject_CallFunction(py_write, "y#", reinterpret_cast<char *>(&ch), 1);
|
||||||
n_written++;
|
n_written++;
|
||||||
}
|
}
|
||||||
if (n_written) {
|
if (n_written) {
|
||||||
|
@ -314,8 +311,8 @@ class streambuf : public std::basic_streambuf<char>
|
||||||
if (which == std::ios_base::in) off -= egptr() - gptr();
|
if (which == std::ios_base::in) off -= egptr() - gptr();
|
||||||
else if (which == std::ios_base::out) off += pptr() - pbase();
|
else if (which == std::ios_base::out) off += pptr() - pbase();
|
||||||
}
|
}
|
||||||
py_seek(off, whence);
|
PyObject_CallFunction(py_seek, "ii", off, whence);
|
||||||
result = off_type(bp::extract<off_type>(py_tell()));
|
result = extract_int<off_type>(PyObject_CallFunction(py_tell, nullptr));
|
||||||
if (which == std::ios_base::in) underflow();
|
if (which == std::ios_base::in) underflow();
|
||||||
}
|
}
|
||||||
return *result;
|
return *result;
|
||||||
|
@ -410,6 +407,15 @@ class streambuf : public std::basic_streambuf<char>
|
||||||
return pos_of_buffer_end_in_py_file + (buf_sought - buf_end);
|
return pos_of_buffer_end_in_py_file + (buf_sought - buf_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T extract_int(PyObject *o)
|
||||||
|
{
|
||||||
|
auto value = PyLong_AsLong(o);
|
||||||
|
Py_DECREF(o);
|
||||||
|
|
||||||
|
return static_cast<T>(value);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class istream : public std::istream
|
class istream : public std::istream
|
||||||
|
@ -442,7 +448,7 @@ struct streambuf_capsule
|
||||||
streambuf python_streambuf;
|
streambuf python_streambuf;
|
||||||
|
|
||||||
streambuf_capsule(
|
streambuf_capsule(
|
||||||
bp::object& python_file_obj,
|
PyObject *python_file_obj,
|
||||||
std::size_t buffer_size=0)
|
std::size_t buffer_size=0)
|
||||||
:
|
:
|
||||||
python_streambuf(python_file_obj, buffer_size)
|
python_streambuf(python_file_obj, buffer_size)
|
||||||
|
@ -452,7 +458,7 @@ struct streambuf_capsule
|
||||||
struct ostream : private streambuf_capsule, streambuf::ostream
|
struct ostream : private streambuf_capsule, streambuf::ostream
|
||||||
{
|
{
|
||||||
ostream(
|
ostream(
|
||||||
bp::object& python_file_obj,
|
PyObject *python_file_obj,
|
||||||
std::size_t buffer_size=0)
|
std::size_t buffer_size=0)
|
||||||
:
|
:
|
||||||
streambuf_capsule(python_file_obj, buffer_size),
|
streambuf_capsule(python_file_obj, buffer_size),
|
||||||
|
@ -461,10 +467,13 @@ struct ostream : private streambuf_capsule, streambuf::ostream
|
||||||
|
|
||||||
~ostream()
|
~ostream()
|
||||||
{
|
{
|
||||||
try {
|
if (this->good())
|
||||||
if (this->good()) this->flush();
|
{
|
||||||
|
this->flush();
|
||||||
}
|
}
|
||||||
catch (bp::error_already_set&) {
|
|
||||||
|
if (PyErr_Occurred() != nullptr)
|
||||||
|
{
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"Problem closing python ostream.\n"
|
"Problem closing python ostream.\n"
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
|
|
||||||
PyObject *xlsx2arrow(PyObject *file)
|
PyObject *xlsx2arrow(PyObject *file)
|
||||||
{
|
{
|
||||||
boost::python::handle<> boost_file_handle(file);
|
xlnt::arrow::streambuf buffer(file);
|
||||||
boost::python::object boost_file(boost_file_handle);
|
|
||||||
boost_adaptbx::python::streambuf buffer(boost_file);
|
|
||||||
std::istream stream(&buffer);
|
std::istream stream(&buffer);
|
||||||
std::shared_ptr<arrow::Schema> schema;
|
std::shared_ptr<arrow::Schema> schema;
|
||||||
std::vector<std::shared_ptr<arrow::Column>> columns;
|
std::vector<std::shared_ptr<arrow::Column>> columns;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user