@@ -127,7 +127,7 @@ function write(w::Writer, p::Ptr, nb::Integer)
127127 w. strm. avail_in = nb
128128 outbuf = Vector {UInt8} (undef, 1024 )
129129
130- while true
130+ GC . @preserve outbuf while true
131131 w. strm. avail_out = length (outbuf)
132132 w. strm. next_out = pointer (outbuf)
133133
@@ -146,16 +146,20 @@ function write(w::Writer, p::Ptr, nb::Integer)
146146 break
147147 end
148148 end
149+ w. strm. next_in = C_NULL
150+ w. strm. next_out = C_NULL
149151 nb
150152end
151153
152- write (w:: Writer , a:: Array{UInt8} ) = write (w, pointer (a), length (a))
154+ function write (w:: Writer , a:: Array{UInt8} )
155+ GC. @preserve a write (w, pointer (a), length (a))
156+ end
153157
154158# If this is not provided, Base.IO write methods will write
155159# arrays one element at a time.
156160function write (w:: Writer , a:: Array{T} ) where T
157161 if isbits (T)
158- write (w, pointer (a), length (a)* sizeof (T))
162+ GC . @preserve a write (w, pointer (a), length (a)* sizeof (T))
159163 else
160164 invoke (write, Tuple{IO,Array}, w, a)
161165 end
@@ -168,20 +172,11 @@ function write(w::Writer, a::SubArray{T,N,A}) where {T,N,A<:Array}
168172 end
169173 colsz = size (a,1 )* sizeof (T)
170174 if N<= 1
171- return write (s, pointer (a, 1 ), colsz)
175+ return GC . @preserve a write (s, pointer (a, 1 ), colsz)
172176 else
173- # WARNING: cartesianmap(f,dims) is deprecated, use for idx = CartesianRange(dims)
174- # f(idx.I...)
175-
176- if VERSION >= v " 0.4.0-"
177- for idx in CartesianRange (tuple (1 , size (a)[2 : end ]. .. ))
178- write (w, pointer (a, idx. I), colsz)
179- end
180- else
181- cartesianmap ((idxs... )-> write (w, pointer (a, idxs), colsz),
182- tuple (1 , size (a)[2 : end ]. .. ))
177+ for idx in CartesianRange (tuple (1 , size (a)[2 : end ]. .. ))
178+ GC. @preserve a write (w, pointer (a, idx. I), colsz)
183179 end
184-
185180 return colsz* Base. trailingsize (a,2 )
186181 end
187182end
@@ -197,30 +192,34 @@ function close(w::Writer)
197192 w. closed = true
198193
199194 # flush zlib buffer using Z_FINISH
200- inbuf = Vector {UInt8} (undef, 0 )
201- w. strm. next_in = pointer (inbuf)
202- w. strm. avail_in = 0
195+ inbuf = Ref {UInt8} (0 )
203196 outbuf = Vector {UInt8} (undef, 1024 )
204- ret = Z_OK
205- while ret != Z_STREAM_END
206- w. strm. avail_out = length (outbuf)
207- w. strm. next_out = pointer (outbuf)
208- ret = ccall ((:deflate , libz),
209- Int32, (Ptr{z_stream}, Int32),
210- Ref (w. strm), Z_FINISH)
211- if ret != Z_OK && ret != Z_STREAM_END
212- error (" Error in zlib deflate stream ($(ret) )." )
213- end
214- n = length (outbuf) - w. strm. avail_out
215- if n > 0 && write (w. io, outbuf[1 : n]) != n
216- error (" short write" )
197+ GC. @preserve inbuf outbuf begin
198+ w. strm. next_in = Base. unsafe_convert (Ptr{UInt8}, inbuf)
199+ w. strm. avail_in = 0
200+ ret = Z_OK
201+ while ret != Z_STREAM_END
202+ w. strm. avail_out = length (outbuf)
203+ w. strm. next_out = pointer (outbuf)
204+ ret = ccall ((:deflate , libz),
205+ Int32, (Ptr{z_stream}, Int32),
206+ Ref (w. strm), Z_FINISH)
207+ if ret != Z_OK && ret != Z_STREAM_END
208+ error (" Error in zlib deflate stream ($(ret) )." )
209+ end
210+ n = length (outbuf) - w. strm. avail_out
211+ if n > 0 && write (w. io, outbuf[1 : n]) != n
212+ error (" short write" )
213+ end
217214 end
218- end
219215
220- ret = ccall ((:deflateEnd , libz), Int32, (Ptr{z_stream},), Ref (w. strm))
221- if ret == Z_STREAM_ERROR
222- error (" Error: zlib deflate stream was prematurely freed." )
216+ ret = ccall ((:deflateEnd , libz), Int32, (Ptr{z_stream},), Ref (w. strm))
217+ if ret == Z_STREAM_ERROR
218+ error (" Error: zlib deflate stream was prematurely freed." )
219+ end
223220 end
221+ w. strm. next_in = C_NULL
222+ w. strm. next_out = C_NULL
224223end
225224
226225
@@ -258,7 +257,8 @@ function fillbuf(r::Reader, minlen::Integer)
258257 r. strm. avail_in = length (input)
259258 # outbuf = Vector{UInt8}(undef, r.bufsize)
260259
261- while true
260+ r_buf = r. buf # GC.@preserve only accepts symbols
261+ GC. @preserve input r_buf while true
262262 # r.strm.next_out = outbuf
263263 # r.strm.avail_out = length(outbuf)
264264 (r. strm. next_out, r. strm. avail_out) = Base. alloc_request (r. buf, convert (UInt, r. bufsize))
@@ -282,6 +282,8 @@ function fillbuf(r::Reader, minlen::Integer)
282282 end
283283 end
284284 end
285+ r. strm. next_in = C_NULL
286+ r. strm. next_out = C_NULL
285287
286288 if ret == Z_STREAM_END
287289 r. stream_end = true
0 commit comments