Skip to content

Commit 69b261c

Browse files
committed
Separate files
1 parent dba25bf commit 69b261c

File tree

4 files changed

+241
-197
lines changed

4 files changed

+241
-197
lines changed

Makefile

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
SRC_DIR = libparse
33
SWIG_IN = $(SRC_DIR)/libparse.i
44
SWIG_OUT = $(SRC_DIR)/libparse_wrap.cpp $(SRC_DIR)/libparse.py
5-
SOURCES = $(SRC_DIR)/libparse_wrap.cpp $(SRC_DIR)/libparse.cpp
5+
SOURCES = $(SRC_DIR)/libparse_wrap.cpp $(SRC_DIR)/py_iostream.cpp $(SRC_DIR)/libparse.cpp
66
OBJECTS = $(patsubst %.cpp,%.o,$(SOURCES))
7-
HEADERS = $(SRC_DIR)/libparse.h $(SRC_DIR)/py_iostream.h
7+
HEADERS = $(SRC_DIR)/libparse.h $(SRC_DIR)/py_iostream.h $(SRC_DIR)/stdio_filebuf.h
88

9-
CXXFLAGS += -g -std=c++11 -I$(shell python3 -c "import sysconfig; print(sysconfig.get_path('include'))")
9+
CXX = clang++
10+
11+
CXXFLAGS += -stdlib=libc++ -g -std=c++11 -I$(shell python3 -c "import sysconfig; print(sysconfig.get_path('include'))")
1012

1113

1214
all: _libparse.so
@@ -37,7 +39,7 @@ regen-patches:
3739

3840
.PHONY: clean
3941
clean:
40-
rm -f $(SRC_DIR)/*.cpp $(SRC_DIR)/*.o $(SRC_DIR)/libparse.py $(SRC_DIR)/libparse.h
42+
rm -f $(SRC_DIR)/libparse*.cpp $(SRC_DIR)/*.o $(SRC_DIR)/libparse.py $(SRC_DIR)/libparse.h
4143
rm -f *.so *.o *.dylib *.dll
4244
rm -rf build/
4345
rm -rf libparse.egg-info/

libparse/py_iostream.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "py_iostream.h"
2+
3+
buffer_pair from_pyobject(PyObject *pyfile)
4+
{
5+
if (pyfile == Py_None) {
6+
throw std::runtime_error("None is not a valid input stream");
7+
}
8+
auto fileno = PyObject_GetAttrString(pyfile, "fileno");
9+
if (fileno == Py_None) {
10+
throw std::runtime_error("Passed object has no fileno() method");
11+
}
12+
13+
auto fd = PyObject_AsFileDescriptor(pyfile);
14+
if (fd == -1) {
15+
throw std::runtime_error("Failed to get file descriptor");
16+
}
17+
18+
auto f = fdopen(fd, "r");
19+
if (!f) {
20+
throw std::runtime_error("Failed to open input stream");
21+
}
22+
23+
return buffer_pair(new stdio_filebuf<char>(f), f);
24+
}

libparse/py_iostream.h

Lines changed: 41 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -1,219 +1,67 @@
11
#define Py_LIMITED_API 0x030600F0
22
#include "Python.h"
3+
#include "stdio_filebuf.h"
34

4-
#include <cstdio>
5-
#include <exception>
6-
#include <iostream>
7-
#include <locale>
5+
typedef std::pair<stdio_filebuf<char> *, FILE *> buffer_pair;
6+
// buffer_pair from_pyobject(PyObject *pyfile);
87

9-
// https://android.googlesource.com/platform/frameworks/native/+/refs/heads/main/services/vr/performanced
10-
// Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
11-
// Copyright (c) 2016 Google, Inc.
12-
//
13-
// Permission is hereby granted, free of charge, to any person obtaining a copy
14-
// of this software and associated documentation files (the "Software"), to deal
15-
// in the Software without restriction, including without limitation the rights
16-
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17-
// copies of the Software, and to permit persons to whom the Software is
18-
// furnished to do so, subject to the following conditions:
19-
//
20-
// The above copyright notice and this permission notice shall be included in
21-
// all copies or substantial portions of the Software.
22-
//
23-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26-
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29-
// THE SOFTWARE.
8+
// struct PyIStream : public std::istream {
9+
// PyIStream(PyObject *pyfile) : buffers(from_pyobject(pyfile)), std::istream(std::get<0>(buffers)) {}
3010

31-
template <class _CharT> class stdio_filebuf : public std::basic_streambuf<_CharT, std::char_traits<_CharT>>
32-
{
33-
public:
34-
typedef _CharT char_type;
35-
typedef std::char_traits<char_type> traits_type;
36-
typedef typename traits_type::int_type int_type;
37-
typedef typename traits_type::pos_type pos_type;
38-
typedef typename traits_type::off_type off_type;
39-
typedef typename traits_type::state_type state_type;
40-
explicit stdio_filebuf(FILE *__fp);
41-
~stdio_filebuf() override;
11+
// ~PyIStream()
12+
// {
13+
// FILE *f;
14+
// stdio_filebuf<char> *buf;
4215

43-
protected:
44-
virtual int_type underflow() override;
45-
virtual int_type uflow() override;
46-
virtual int_type pbackfail(int_type __c = traits_type::eof()) override;
47-
virtual void imbue(const std::locale &__loc) override;
16+
// if ((f = std::get<1>(buffers))) {
17+
// fclose(f);
18+
// }
19+
// if ((buf = std::get<0>(buffers))) {
20+
// delete buf;
21+
// }
22+
// }
4823

49-
private:
50-
FILE *__file_;
51-
const std::codecvt<char_type, char, state_type> *__cv_;
52-
state_type __st_;
53-
int __encoding_;
54-
int_type __last_consumed_;
55-
bool __last_consumed_is_next_;
56-
bool __always_noconv_;
57-
stdio_filebuf(const stdio_filebuf &);
58-
stdio_filebuf &operator=(const stdio_filebuf &);
59-
int_type __getchar(bool __consume);
60-
static const int __limit = 8;
61-
};
62-
template <class _CharT>
63-
stdio_filebuf<_CharT>::stdio_filebuf(FILE *__fp) : __file_(__fp), __last_consumed_(traits_type::eof()), __last_consumed_is_next_(false)
64-
{
65-
imbue(this->getloc());
66-
}
67-
template <class _CharT> stdio_filebuf<_CharT>::~stdio_filebuf()
68-
{
69-
if (__file_)
70-
fclose(__file_);
71-
}
72-
template <class _CharT> void stdio_filebuf<_CharT>::imbue(const std::locale &__loc)
73-
{
74-
__cv_ = &std::use_facet<std::codecvt<char_type, char, state_type>>(__loc);
75-
__encoding_ = __cv_->encoding();
76-
__always_noconv_ = __cv_->always_noconv();
77-
if (__encoding_ > __limit)
78-
throw std::runtime_error("unsupported locale for standard io");
79-
}
80-
template <class _CharT> typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::underflow() { return __getchar(false); }
81-
template <class _CharT> typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::uflow() { return __getchar(true); }
82-
template <class _CharT> typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::__getchar(bool __consume)
83-
{
84-
if (__last_consumed_is_next_) {
85-
int_type __result = __last_consumed_;
86-
if (__consume) {
87-
__last_consumed_ = traits_type::eof();
88-
__last_consumed_is_next_ = false;
89-
}
90-
return __result;
91-
}
92-
char __extbuf[__limit];
93-
int __nread = std::max(1, __encoding_);
94-
for (int __i = 0; __i < __nread; ++__i) {
95-
int __c = getc(__file_);
96-
if (__c == EOF)
97-
return traits_type::eof();
98-
__extbuf[__i] = static_cast<char>(__c);
99-
}
100-
char_type __1buf;
101-
if (__always_noconv_)
102-
__1buf = static_cast<char_type>(__extbuf[0]);
103-
else {
104-
const char *__enxt;
105-
char_type *__inxt;
106-
std::codecvt_base::result __r;
107-
do {
108-
state_type __sv_st = __st_;
109-
__r = __cv_->in(__st_, __extbuf, __extbuf + __nread, __enxt, &__1buf, &__1buf + 1, __inxt);
110-
switch (__r) {
111-
case std::codecvt_base::ok:
112-
break;
113-
case std::codecvt_base::partial:
114-
__st_ = __sv_st;
115-
if (__nread == sizeof(__extbuf))
116-
return traits_type::eof();
117-
{
118-
int __c = getc(__file_);
119-
if (__c == EOF)
120-
return traits_type::eof();
121-
__extbuf[__nread] = static_cast<char>(__c);
122-
}
123-
++__nread;
124-
break;
125-
case std::codecvt_base::error:
126-
return traits_type::eof();
127-
case std::codecvt_base::noconv:
128-
__1buf = static_cast<char_type>(__extbuf[0]);
129-
break;
130-
}
131-
} while (__r == std::codecvt_base::partial);
132-
}
133-
if (!__consume) {
134-
for (int __i = __nread; __i > 0;) {
135-
if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF)
136-
return traits_type::eof();
24+
// private:
25+
// buffer_pair buffers;
26+
// };
27+
28+
struct PyIStream : public std::istream {
29+
PyIStream(PyObject *pyfile)
30+
{
31+
if (pyfile == Py_None) {
32+
throw std::runtime_error("None is not a valid input stream");
13733
}
138-
} else
139-
__last_consumed_ = traits_type::to_int_type(__1buf);
140-
return traits_type::to_int_type(__1buf);
141-
}
142-
template <class _CharT> typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::pbackfail(int_type __c)
143-
{
144-
if (traits_type::eq_int_type(__c, traits_type::eof())) {
145-
if (!__last_consumed_is_next_) {
146-
__c = __last_consumed_;
147-
__last_consumed_is_next_ = !traits_type::eq_int_type(__last_consumed_, traits_type::eof());
34+
auto fileno = PyObject_GetAttrString(pyfile, "fileno");
35+
if (!fileno) {
36+
throw std::runtime_error("Passed object has no fileno() method");
14837
}
149-
return __c;
150-
}
151-
if (__last_consumed_is_next_) {
152-
char __extbuf[__limit];
153-
char *__enxt;
154-
const char_type __ci = traits_type::to_char_type(__last_consumed_);
155-
const char_type *__inxt;
156-
switch (__cv_->out(__st_, &__ci, &__ci + 1, __inxt, __extbuf, __extbuf + sizeof(__extbuf), __enxt)) {
157-
case std::codecvt_base::ok:
158-
break;
159-
case std::codecvt_base::noconv:
160-
__extbuf[0] = static_cast<char>(__last_consumed_);
161-
__enxt = __extbuf + 1;
162-
break;
163-
case std::codecvt_base::partial:
164-
case std::codecvt_base::error:
165-
return traits_type::eof();
38+
fd = PyObject_AsFileDescriptor(pyfile);
39+
if (fd == -1) {
40+
throw std::runtime_error("Failed to get file descriptor");
16641
}
167-
while (__enxt > __extbuf)
168-
if (ungetc(*--__enxt, __file_) == EOF)
169-
return traits_type::eof();
170-
}
171-
__last_consumed_ = __c;
172-
__last_consumed_is_next_ = true;
173-
return __c;
174-
}
17542

176-
typedef std::pair<stdio_filebuf<char> *, FILE *> buffer_pair;
177-
static buffer_pair from_pyobject(PyObject *pyfile)
178-
{
179-
if (pyfile == Py_None) {
180-
throw std::runtime_error("None is not a valid input stream");
181-
}
182-
auto fileno = PyObject_GetAttrString(pyfile, "fileno");
183-
if (!fileno) {
184-
throw std::runtime_error("Passed object has no fileno() method");
185-
}
43+
f = fdopen(fd, "r");
44+
if (!f) {
45+
throw std::runtime_error("Failed to open input stream");
46+
}
18647

187-
auto fd = PyObject_AsFileDescriptor(pyfile);
188-
if (fd == -1) {
189-
throw std::runtime_error("Failed to get file descriptor");
190-
}
48+
buf = new stdio_filebuf<char>(f);
19149

192-
auto f = fdopen(fd, "r");
193-
if (!f) {
194-
throw std::runtime_error("Failed to open input stream");
50+
init(buf);
19551
}
19652

197-
return buffer_pair(new stdio_filebuf<char>(f), f);
198-
}
199-
200-
struct PyIStream : public std::istream {
201-
PyIStream(PyObject *pyfile) : buffers(from_pyobject(pyfile)), std::istream(std::get<0>(buffers)) {}
202-
20353
~PyIStream()
20454
{
205-
FILE *f;
206-
stdio_filebuf<char> *buf;
207-
208-
if ((f = std::get<1>(buffers))) {
55+
if (f) {
20956
fclose(f);
21057
}
211-
if ((buf = std::get<0>(buffers))) {
58+
if (buf) {
21259
free(buf);
21360
}
21461
}
21562

21663
private:
217-
buffer_pair buffers;
64+
int fd = -1;
65+
FILE *f = nullptr;
21866
stdio_filebuf<char> *buf = nullptr;
21967
};

0 commit comments

Comments
 (0)