@@ -10,7 +10,7 @@ If `text=false` then `o` must be a binary stream and arbitrary binary I/O is pos
10
10
For efficiency, reads and writes are buffered before being sent to `o`. The size of the buffer is `buflen`.
11
11
"""
12
12
mutable struct PyIO <: IO
13
- o :: PyObject
13
+ ref :: PyRef
14
14
# true to close the file automatically
15
15
own :: Bool
16
16
# true if `o` is text, false if binary
@@ -24,8 +24,8 @@ mutable struct PyIO <: IO
24
24
obuflen :: Int
25
25
obuf :: Vector{UInt8}
26
26
27
- function PyIO (o:: PyObject ; own:: Bool = false , text:: Union{Missing,Bool} = missing , buflen:: Integer = 4096 , ibuflen= buflen, obuflen= buflen)
28
- io = new (PyObject (o), own, text=== missing ? pyisinstance (o, pyiomodule. TextIOBase) : text, false , ibuflen, UInt8[], obuflen, UInt8[])
27
+ function PyIO (o; own:: Bool = false , text:: Union{Missing,Bool} = missing , buflen:: Integer = 4096 , ibuflen= buflen, obuflen= buflen)
28
+ io = new (PyRef (o), own, text=== missing ? pyisinstance (o, pyiomodule () . TextIOBase) : text, false , ibuflen, UInt8[], obuflen, UInt8[])
29
29
finalizer (io) do io
30
30
io. own ? close (io) : flush (io)
31
31
end
@@ -34,6 +34,11 @@ mutable struct PyIO <: IO
34
34
end
35
35
export PyIO
36
36
37
+ ispyreftype (:: Type{PyIO} ) = true
38
+ pyptr (io:: PyIO ) = pyptr (io. ref)
39
+ Base. unsafe_convert (:: Type{CPyPtr} , io:: PyIO ) = checknull (pyptr (io))
40
+ C. PyObject_TryConvert__initial (o, :: Type{PyIO} ) = C. putresult (PyIO, PyIO (pyborrowedref (o)))
41
+
37
42
"""
38
43
PyIO(f, o; ...)
39
44
@@ -50,39 +55,32 @@ function PyIO(f::Function, o; opts...)
50
55
end
51
56
end
52
57
53
- pyobject (io:: PyIO ) = io. o
54
-
55
58
# If obuf is non-empty, write it to the underlying stream.
56
59
function putobuf (io:: PyIO )
57
60
if ! isempty (io. obuf)
58
- io. text ? io . o . write ( String ( io. obuf)) : io . o . write (io. obuf)
61
+ @py ` $ io .write( $(io . text ? pystr ( io. obuf) : pybytes (io. obuf)) ) `
59
62
empty! (io. obuf)
60
63
end
61
64
nothing
62
65
end
63
66
64
67
# If ibuf is empty, read some more from the underlying stream.
65
68
# After this call, if ibuf is empty then we are at EOF.
69
+ # TODO : in binary mode, `io.readinto()` to avoid copying data
66
70
function getibuf (io:: PyIO )
67
71
if isempty (io. ibuf)
68
- if io. text
69
- append! (io. ibuf, PyVector {UInt8,UInt8,false,true} (pystr_asutf8string (io. o. read (io. ibuflen))))
70
- else
71
- resize! (io. ibuf, io. ibuflen)
72
- n = io. o. readinto (io. ibuf). jl!i
73
- resize! (io. ibuf, n)
74
- end
72
+ append! (io. ibuf, @pyv ` $io .read($(io. ibuflen) )` :: Vector{UInt8} )
75
73
end
76
74
nothing
77
75
end
78
76
79
77
function Base. flush (io:: PyIO )
80
78
putobuf (io)
81
- io. o . flush ()
79
+ @py ` $ io .flush()`
82
80
nothing
83
81
end
84
82
85
- Base. close (io:: PyIO ) = (flush (io); io. o . close (); nothing )
83
+ Base. close (io:: PyIO ) = (flush (io); @py ` $ io .close()` ; nothing )
86
84
87
85
function Base. eof (io:: PyIO )
88
86
if io. eof
@@ -95,13 +93,13 @@ function Base.eof(io::PyIO)
95
93
end
96
94
end
97
95
98
- Base. fd (io:: PyIO ) = io. o . fileno (). jl!i
96
+ Base. fd (io:: PyIO ) = @pyv ` $ io .fileno()` :: Int
99
97
100
- Base. isreadable (io:: PyIO ) = io. o . readable (). jl!b
98
+ Base. isreadable (io:: PyIO ) = @pyv ` $ io .readable()` :: Bool
101
99
102
- Base. iswritable (io:: PyIO ) = io. o . writable (). jl!b
100
+ Base. iswritable (io:: PyIO ) = @pyv ` $ io .writable()` :: Bool
103
101
104
- Base. isopen (io:: PyIO ) = ! io. o . closed. jl!b
102
+ Base. isopen (io:: PyIO ) = @pyv ` not $ io .closed` :: Bool
105
103
106
104
function Base. unsafe_write (io:: PyIO , ptr:: Ptr{UInt8} , n:: UInt )
107
105
while true
@@ -150,7 +148,7 @@ function Base.seek(io::PyIO, pos::Integer)
150
148
putobuf (io)
151
149
empty! (io. ibuf)
152
150
io. eof = false
153
- io. o . seek (pos, 0 )
151
+ @py ` $ io .seek($ pos , 0)`
154
152
io
155
153
end
156
154
@@ -164,15 +162,15 @@ function Base.seekstart(io::PyIO)
164
162
putobuf (io)
165
163
empty! (io. ibuf)
166
164
io. eof = false
167
- io. o . seek (0 , 0 )
165
+ @py ` $ io .seek(0, 0)`
168
166
io
169
167
end
170
168
171
169
function Base. seekend (io:: PyIO )
172
170
putobuf (io)
173
171
empty! (io. ibuf)
174
172
io. eof = false
175
- io. o . seek (0 , 2 )
173
+ @py ` $ io .seek(0, 2)`
176
174
io
177
175
end
178
176
@@ -188,7 +186,7 @@ function Base.skip(io::PyIO, n::Integer)
188
186
if 0 ≤ n ≤ io. ibuflen
189
187
read (io, n)
190
188
else
191
- io. o . seek (n - length (io. ibuf), 1 )
189
+ @py ` $ io .seek($( n - length (io. ibuf)) , 1)`
192
190
empty! (io. ibuf)
193
191
io. eof = false
194
192
end
@@ -199,11 +197,11 @@ function Base.position(io::PyIO)
199
197
putobuf (io)
200
198
if io. text
201
199
if isempty (io. ibuf)
202
- io. o . position (). jl!i
200
+ @pyv ` $ io .position()` :: Int
203
201
else
204
202
error (" `position(io)` text PyIO streams only implemented for empty input buffer (e.g. do `read(io, length(io.ibuf))` first)" )
205
203
end
206
204
else
207
- io. o . position (). jl!i - length (io. ibuf)
205
+ ( @py ` $ io .position()` :: Int ) - length (io. ibuf)
208
206
end
209
207
end
0 commit comments