StatProfilerHTML.jl report
Generated on tor 10 okt 2019 11:38:33
File source code
Line Exclusive Inclusive Code
1 # This file is a part of Julia. License is MIT: https://julialang.org/license
2
3 # Generic IO stubs -- all subtypes should implement these (if meaningful)
4
5 """
6 EOFError()
7
8 No more data was available to read from a file or stream.
9 """
10 struct EOFError <: Exception end
11
12 """
13 SystemError(prefix::AbstractString, [errno::Int32])
14
15 A system call failed with an error code (in the `errno` global variable).
16 """
17 struct SystemError <: Exception
18 prefix::AbstractString
19 errnum::Int32
20 extrainfo
21 SystemError(p::AbstractString, e::Integer, extrainfo) = new(p, e, extrainfo)
22 SystemError(p::AbstractString, e::Integer) = new(p, e, nothing)
23 SystemError(p::AbstractString) = new(p, Libc.errno())
24 end
25
26 lock(::IO) = nothing
27 unlock(::IO) = nothing
28 reseteof(x::IO) = nothing
29
30 const SZ_UNBUFFERED_IO = 65536
31 buffer_writes(x::IO, bufsize=SZ_UNBUFFERED_IO) = x
32
33 """
34 isopen(object) -> Bool
35
36 Determine whether an object - such as a stream or timer
37 -- is not yet closed. Once an object is closed, it will never produce a new event.
38 However, since a closed stream may still have data to read in its buffer,
39 use [`eof`](@ref) to check for the ability to read data.
40 Use the `FileWatching` package to be notified when a stream might be writable or readable.
41
42 # Examples
43 ```jldoctest
44 julia> io = open("my_file.txt", "w+");
45
46 julia> isopen(io)
47 true
48
49 julia> close(io)
50
51 julia> isopen(io)
52 false
53 ```
54 """
55 function isopen end
56
57 """
58 close(stream)
59
60 Close an I/O stream. Performs a [`flush`](@ref) first.
61 """
62 function close end
63 function flush end
64 function wait_connected end
65 function wait_readnb end
66 function wait_readbyte end
67 function wait_close end
68 function bytesavailable end
69
70 """
71 readavailable(stream)
72
73 Read all available data on the stream, blocking the task only if no data is available. The
74 result is a `Vector{UInt8,1}`.
75 """
76 function readavailable end
77
78 """
79 isreadable(io) -> Bool
80
81 Return `true` if the specified IO object is readable (if that can be determined).
82
83 # Examples
84 ```jldoctest
85 julia> open("myfile.txt", "w") do io
86 print(io, "Hello world!");
87 isreadable(io)
88 end
89 false
90
91 julia> open("myfile.txt", "r") do io
92 isreadable(io)
93 end
94 true
95
96 julia> rm("myfile.txt")
97 ```
98 """
99 function isreadable end
100
101 """
102 iswritable(io) -> Bool
103
104 Return `true` if the specified IO object is writable (if that can be determined).
105
106 # Examples
107 ```jldoctest
108 julia> open("myfile.txt", "w") do io
109 print(io, "Hello world!");
110 iswritable(io)
111 end
112 true
113
114 julia> open("myfile.txt", "r") do io
115 iswritable(io)
116 end
117 false
118
119 julia> rm("myfile.txt")
120 ```
121 """
122 function iswritable end
123 function copy end
124 function eof end
125
126 """
127 read(io::IO, T)
128
129 Read a single value of type `T` from `io`, in canonical binary representation.
130
131 read(io::IO, String)
132
133 Read the entirety of `io`, as a `String`.
134
135 # Examples
136 ```jldoctest
137 julia> io = IOBuffer("JuliaLang is a GitHub organization");
138
139 julia> read(io, Char)
140 'J': ASCII/Unicode U+004a (category Lu: Letter, uppercase)
141
142 julia> io = IOBuffer("JuliaLang is a GitHub organization");
143
144 julia> read(io, String)
145 "JuliaLang is a GitHub organization"
146 ```
147 """
148 read(stream, t)
149
150 """
151 write(io::IO, x)
152 write(filename::AbstractString, x)
153
154 Write the canonical binary representation of a value to the given I/O stream or file.
155 Return the number of bytes written into the stream. See also [`print`](@ref) to
156 write a text representation (with an encoding that may depend upon `io`).
157
158 You can write multiple values with the same `write` call. i.e. the following are equivalent:
159
160 write(io, x, y...)
161 write(io, x) + write(io, y...)
162
163 # Examples
164 ```jldoctest
165 julia> io = IOBuffer();
166
167 julia> write(io, "JuliaLang is a GitHub organization.", " It has many members.")
168 56
169
170 julia> String(take!(io))
171 "JuliaLang is a GitHub organization. It has many members."
172
173 julia> write(io, "Sometimes those members") + write(io, " write documentation.")
174 44
175
176 julia> String(take!(io))
177 "Sometimes those members write documentation."
178 ```
179 """
180 function write end
181
182 read(s::IO, ::Type{UInt8}) = error(typeof(s)," does not support byte I/O")
183 write(s::IO, x::UInt8) = error(typeof(s)," does not support byte I/O")
184
185 """
186 unsafe_write(io::IO, ref, nbytes::UInt)
187
188 Copy `nbytes` from `ref` (converted to a pointer) into the `IO` object.
189
190 It is recommended that subtypes `T<:IO` override the following method signature
191 to provide more efficient implementations:
192 `unsafe_write(s::T, p::Ptr{UInt8}, n::UInt)`
193 """
194 function unsafe_write(s::IO, p::Ptr{UInt8}, n::UInt)
195 written::Int = 0
196 for i = 1:n
197 written += write(s, unsafe_load(p, i))
198 end
199 return written
200 end
201
202 """
203 unsafe_read(io::IO, ref, nbytes::UInt)
204
205 Copy `nbytes` from the `IO` stream object into `ref` (converted to a pointer).
206
207 It is recommended that subtypes `T<:IO` override the following method signature
208 to provide more efficient implementations:
209 `unsafe_read(s::T, p::Ptr{UInt8}, n::UInt)`
210 """
211 function unsafe_read(s::IO, p::Ptr{UInt8}, n::UInt)
212 for i = 1:n
213 unsafe_store!(p, read(s, UInt8)::UInt8, i)
214 end
215 nothing
216 end
217
218
219 # Generic wrappers around other IO objects
220 abstract type AbstractPipe <: IO end
221 function pipe_reader end
222 function pipe_writer end
223
224 write(io::AbstractPipe, byte::UInt8) = write(pipe_writer(io), byte)
225 unsafe_write(io::AbstractPipe, p::Ptr{UInt8}, nb::UInt) = unsafe_write(pipe_writer(io), p, nb)
226 buffer_writes(io::AbstractPipe, args...) = buffer_writes(pipe_writer(io), args...)
227 flush(io::AbstractPipe) = flush(pipe_writer(io))
228
229 read(io::AbstractPipe, byte::Type{UInt8}) = read(pipe_reader(io), byte)
230 unsafe_read(io::AbstractPipe, p::Ptr{UInt8}, nb::UInt) = unsafe_read(pipe_reader(io), p, nb)
231 read(io::AbstractPipe) = read(pipe_reader(io))
232 readuntil(io::AbstractPipe, arg::UInt8; kw...) = readuntil(pipe_reader(io), arg; kw...)
233 readuntil(io::AbstractPipe, arg::AbstractChar; kw...) = readuntil(pipe_reader(io), arg; kw...)
234 readuntil(io::AbstractPipe, arg::AbstractString; kw...) = readuntil(pipe_reader(io), arg; kw...)
235 readuntil(io::AbstractPipe, arg::AbstractVector; kw...) = readuntil(pipe_reader(io), arg; kw...)
236 readuntil_vector!(io::AbstractPipe, target::AbstractVector, keep::Bool, out) = readuntil_vector!(pipe_reader(io), target, keep, out)
237
238 for f in (
239 # peek/mark interface
240 :peek, :mark, :unmark, :reset, :ismarked,
241 # Simple reader functions
242 :readavailable, :isreadable)
243 @eval $(f)(io::AbstractPipe) = $(f)(pipe_reader(io))
244 end
245
246 iswritable(io::AbstractPipe) = iswritable(pipe_writer(io))
247 isopen(io::AbstractPipe) = isopen(pipe_writer(io)) || isopen(pipe_reader(io))
248 close(io::AbstractPipe) = (close(pipe_writer(io)); close(pipe_reader(io)))
249 wait_readnb(io::AbstractPipe, nb::Int) = wait_readnb(pipe_reader(io), nb)
250 wait_readbyte(io::AbstractPipe, byte::UInt8) = wait_readbyte(pipe_reader(io), byte)
251 wait_close(io::AbstractPipe) = (wait_close(pipe_writer(io)); wait_close(pipe_reader(io)))
252
253 """
254 bytesavailable(io)
255
256 Return the number of bytes available for reading before a read from this stream or buffer will block.
257
258 # Examples
259 ```jldoctest
260 julia> io = IOBuffer("JuliaLang is a GitHub organization");
261
262 julia> bytesavailable(io)
263 34
264 ```
265 """
266 bytesavailable(io::AbstractPipe) = bytesavailable(pipe_reader(io))
267
268 """
269 eof(stream) -> Bool
270
271 Test whether an I/O stream is at end-of-file. If the stream is not yet exhausted, this
272 function will block to wait for more data if necessary, and then return `false`. Therefore
273 it is always safe to read one byte after seeing `eof` return `false`. `eof` will return
274 `false` as long as buffered data is still available, even if the remote end of a connection
275 is closed.
276 """
277 eof(io::AbstractPipe) = eof(pipe_reader(io))
278 reseteof(io::AbstractPipe) = reseteof(pipe_reader(io))
279
280
281 # Exception-safe wrappers (io = open(); try f(io) finally close(io))
282
283 write(filename::AbstractString, a1, args...) = open(io->write(io, a1, args...), filename, "w")
284
285 """
286 read(filename::AbstractString, args...)
287
288 Open a file and read its contents. `args` is passed to `read`: this is equivalent to
289 `open(io->read(io, args...), filename)`.
290
291 read(filename::AbstractString, String)
292
293 Read the entire contents of a file as a string.
294 """
295 read(filename::AbstractString, args...) = open(io->read(io, args...), filename)
296
297 read(filename::AbstractString, ::Type{T}) where {T} = open(io->read(io, T), filename)
298
299 """
300 read!(stream::IO, array::Union{Array, BitArray})
301 read!(filename::AbstractString, array::Union{Array, BitArray})
302
303 Read binary data from an I/O stream or file, filling in `array`.
304 """
305 function read! end
306
307 read!(filename::AbstractString, a) = open(io->read!(io, a), filename)
308
309 """
310 readuntil(stream::IO, delim; keep::Bool = false)
311 readuntil(filename::AbstractString, delim; keep::Bool = false)
312
313 Read a string from an I/O stream or a file, up to the given delimiter.
314 The delimiter can be a `UInt8`, `AbstractChar`, string, or vector.
315 Keyword argument `keep` controls whether the delimiter is included in the result.
316 The text is assumed to be encoded in UTF-8.
317
318 # Examples
319 ```jldoctest
320 julia> open("my_file.txt", "w") do io
321 write(io, "JuliaLang is a GitHub organization.\\nIt has many members.\\n");
322 end
323 57
324
325 julia> readuntil("my_file.txt", 'L')
326 "Julia"
327
328 julia> readuntil("my_file.txt", '.', keep = true)
329 "JuliaLang is a GitHub organization."
330
331 julia> rm("my_file.txt")
332 ```
333 """
334 readuntil(filename::AbstractString, args...; kw...) = open(io->readuntil(io, args...; kw...), filename)
335
336 """
337 readline(io::IO=stdin; keep::Bool=false)
338 readline(filename::AbstractString; keep::Bool=false)
339
340 Read a single line of text from the given I/O stream or file (defaults to `stdin`).
341 When reading from a file, the text is assumed to be encoded in UTF-8. Lines in the
342 input end with `'\\n'` or `"\\r\\n"` or the end of an input stream. When `keep` is
343 false (as it is by default), these trailing newline characters are removed from the
344 line before it is returned. When `keep` is true, they are returned as part of the
345 line.
346
347 # Examples
348 ```jldoctest
349 julia> open("my_file.txt", "w") do io
350 write(io, "JuliaLang is a GitHub organization.\\nIt has many members.\\n");
351 end
352 57
353
354 julia> readline("my_file.txt")
355 "JuliaLang is a GitHub organization."
356
357 julia> readline("my_file.txt", keep=true)
358 "JuliaLang is a GitHub organization.\\n"
359
360 julia> rm("my_file.txt")
361 ```
362 """
363 function readline(filename::AbstractString; keep::Bool=false)
364 open(filename) do f
365 readline(f, keep=keep)
366 end
367 end
368
369 function readline(s::IO=stdin; keep::Bool=false)
370 line = readuntil(s, 0x0a, keep=true)
371 i = length(line)
372 if keep || i == 0 || line[i] != 0x0a
373 return String(line)
374 elseif i < 2 || line[i-1] != 0x0d
375 return String(resize!(line,i-1))
376 else
377 return String(resize!(line,i-2))
378 end
379 end
380
381 """
382 readlines(io::IO=stdin; keep::Bool=false)
383 readlines(filename::AbstractString; keep::Bool=false)
384
385 Read all lines of an I/O stream or a file as a vector of strings. Behavior is
386 equivalent to saving the result of reading [`readline`](@ref) repeatedly with the same
387 arguments and saving the resulting lines as a vector of strings.
388
389 # Examples
390 ```jldoctest
391 julia> open("my_file.txt", "w") do io
392 write(io, "JuliaLang is a GitHub organization.\\nIt has many members.\\n");
393 end
394 57
395
396 julia> readlines("my_file.txt")
397 2-element Array{String,1}:
398 "JuliaLang is a GitHub organization."
399 "It has many members."
400
401 julia> readlines("my_file.txt", keep=true)
402 2-element Array{String,1}:
403 "JuliaLang is a GitHub organization.\\n"
404 "It has many members.\\n"
405
406 julia> rm("my_file.txt")
407 ```
408 """
409 function readlines(filename::AbstractString; kw...)
410 open(filename) do f
411 readlines(f; kw...)
412 end
413 end
414 readlines(s=stdin; kw...) = collect(eachline(s; kw...))
415
416 ## byte-order mark, ntoh & hton ##
417
418 let a = UInt32[0x01020304]
419 endian_bom = GC.@preserve a unsafe_load(convert(Ptr{UInt8}, pointer(a)))
420 global ntoh, hton, ltoh, htol
421 if endian_bom == 0x01
422 ntoh(x) = x
423 hton(x) = x
424 ltoh(x) = bswap(x)
425 htol(x) = bswap(x)
426 const global ENDIAN_BOM = 0x01020304
427 elseif endian_bom == 0x04
428 ntoh(x) = bswap(x)
429 hton(x) = bswap(x)
430 ltoh(x) = x
431 htol(x) = x
432 const global ENDIAN_BOM = 0x04030201
433 else
434 error("seriously? what is this machine?")
435 end
436 end
437
438 """
439 ENDIAN_BOM
440
441 The 32-bit byte-order-mark indicates the native byte order of the host machine.
442 Little-endian machines will contain the value `0x04030201`. Big-endian machines will contain
443 the value `0x01020304`.
444 """
445 ENDIAN_BOM
446
447 """
448 ntoh(x)
449
450 Convert the endianness of a value from Network byte order (big-endian) to that used by the Host.
451 """
452 ntoh(x)
453
454 """
455 hton(x)
456
457 Convert the endianness of a value from that used by the Host to Network byte order (big-endian).
458 """
459 hton(x)
460
461 """
462 ltoh(x)
463
464 Convert the endianness of a value from Little-endian to that used by the Host.
465 """
466 ltoh(x)
467
468 """
469 htol(x)
470
471 Convert the endianness of a value from that used by the Host to Little-endian.
472 """
473 htol(x)
474
475
476 """
477 isreadonly(io) -> Bool
478
479 Determine whether a stream is read-only.
480
481 # Examples
482 ```jldoctest
483 julia> io = IOBuffer("JuliaLang is a GitHub organization");
484
485 julia> isreadonly(io)
486 true
487
488 julia> io = IOBuffer();
489
490 julia> isreadonly(io)
491 false
492 ```
493 """
494 isreadonly(s) = isreadable(s) && !iswritable(s)
495
496 ## binary I/O ##
497
498 write(io::IO, x) = throw(MethodError(write, (io, x)))
499 function write(io::IO, x1, xs...)
500 written::Int = write(io, x1)
501 for x in xs
502 written += write(io, x)
503 end
504 return written
505 end
506
507 @noinline unsafe_write(s::IO, p::Ref{T}, n::Integer) where {T} =
508 unsafe_write(s, unsafe_convert(Ref{T}, p)::Ptr, n) # mark noinline to ensure ref is gc-rooted somewhere (by the caller)
509 1 (2.38%)
1 (2.38%) samples spent in unsafe_write
0 (ex.), 1 (100.00%) (incl.) when called from _show line 128
1 (100.00%) samples spent calling unsafe_write
unsafe_write(s::IO, p::Ptr, n::Integer) = unsafe_write(s, convert(Ptr{UInt8}, p), convert(UInt, n))
510 write(s::IO, x::Ref{T}) where {T} = unsafe_write(s, x, Core.sizeof(T))
511 write(s::IO, x::Int8) = write(s, reinterpret(UInt8, x))
512 function write(s::IO, x::Union{Int16,UInt16,Int32,UInt32,Int64,UInt64,Int128,UInt128,Float16,Float32,Float64})
513 return write(s, Ref(x))
514 end
515
516 write(s::IO, x::Bool) = write(s, UInt8(x))
517 write(to::IO, p::Ptr) = write(to, convert(UInt, p))
518
519 function write(s::IO, A::AbstractArray)
520 if !isbitstype(eltype(A))
521 error("`write` is not supported on non-isbits arrays")
522 end
523 nb = 0
524 for a in A
525 nb += write(s, a)
526 end
527 return nb
528 end
529
530 function write(s::IO, a::Array)
531 if isbitstype(eltype(a))
532 return GC.@preserve a unsafe_write(s, pointer(a), sizeof(a))
533 else
534 error("`write` is not supported on non-isbits arrays")
535 end
536 end
537
538 function write(s::IO, a::SubArray{T,N,<:Array}) where {T,N}
539 if !isbitstype(T) || !isa(a, StridedArray)
540 return invoke(write, Tuple{IO, AbstractArray}, s, a)
541 end
542 elsz = sizeof(T)
543 colsz = size(a,1) * elsz
544 GC.@preserve a if stride(a,1) != 1
545 for idxs in CartesianIndices(size(a))
546 unsafe_write(s, pointer(a, idxs.I), elsz)
547 end
548 return elsz * length(a)
549 elseif N <= 1
550 return unsafe_write(s, pointer(a, 1), colsz)
551 else
552 for idxs in CartesianIndices((1, size(a)[2:end]...))
553 unsafe_write(s, pointer(a, idxs.I), colsz)
554 end
555 return colsz * trailingsize(a,2)
556 end
557 end
558
559 function write(io::IO, c::Char)
560 u = bswap(reinterpret(UInt32, c))
561 n = 1
562 while true
563 write(io, u % UInt8)
564 (u >>= 8) == 0 && return n
565 n += 1
566 end
567 end
568 # write(io, ::AbstractChar) is not defined: implementations
569 # must provide their own encoding-specific method.
570
571 function write(io::IO, s::Symbol)
572 pname = unsafe_convert(Ptr{UInt8}, s)
573 return unsafe_write(io, pname, Int(ccall(:strlen, Csize_t, (Cstring,), pname)))
574 end
575
576 function write(to::IO, from::IO)
577 n = 0
578 while !eof(from)
579 n += write(to, readavailable(from))
580 end
581 return n
582 end
583
584 @noinline unsafe_read(s::IO, p::Ref{T}, n::Integer) where {T} = unsafe_read(s, unsafe_convert(Ref{T}, p)::Ptr, n) # mark noinline to ensure ref is gc-rooted somewhere (by the caller)
585 unsafe_read(s::IO, p::Ptr, n::Integer) = unsafe_read(s, convert(Ptr{UInt8}, p), convert(UInt, n))
586 read!(s::IO, x::Ref{T}) where {T} = (unsafe_read(s, x, Core.sizeof(T)); x)
587
588 read(s::IO, ::Type{Int8}) = reinterpret(Int8, read(s, UInt8))
589 function read(s::IO, T::Union{Type{Int16},Type{UInt16},Type{Int32},Type{UInt32},Type{Int64},Type{UInt64},Type{Int128},Type{UInt128},Type{Float16},Type{Float32},Type{Float64}})
590 return read!(s, Ref{T}(0))[]::T
591 end
592
593 read(s::IO, ::Type{Bool}) = (read(s, UInt8) != 0)
594 read(s::IO, ::Type{Ptr{T}}) where {T} = convert(Ptr{T}, read(s, UInt))
595
596 function read!(s::IO, a::Array{UInt8})
597 GC.@preserve a unsafe_read(s, pointer(a), sizeof(a))
598 return a
599 end
600
601 function read!(s::IO, a::Array{T}) where T
602 if isbitstype(T)
603 GC.@preserve a unsafe_read(s, pointer(a), sizeof(a))
604 else
605 for i in eachindex(a)
606 a[i] = read(s, T)
607 end
608 end
609 return a
610 end
611
612 function read(io::IO, ::Type{Char})
613 b0 = read(io, UInt8)
614 l = 8(4-leading_ones(b0))
615 c = UInt32(b0) << 24
616 if l < 24
617 s = 16
618 while s ≥ l && !eof(io)
619 peek(io) & 0xc0 == 0x80 || break
620 b = read(io, UInt8)
621 c |= UInt32(b) << s
622 s -= 8
623 end
624 end
625 return reinterpret(Char, c)
626 end
627 # read(io, T) is not defined for other AbstractChar: implementations
628 # must provide their own encoding-specific method.
629
630 # readuntil_string is useful below since it has
631 # an optimized method for s::IOStream
632 readuntil_string(s::IO, delim::UInt8, keep::Bool) = String(readuntil(s, delim, keep=keep))
633
634 function readuntil(s::IO, delim::AbstractChar; keep::Bool=false)
635 if delim ≤ '\x7f'
636 return readuntil_string(s, delim % UInt8, keep)
637 end
638 out = IOBuffer()
639 while !eof(s)
640 c = read(s, Char)
641 if c == delim
642 keep && write(out, c)
643 break
644 end
645 write(out, c)
646 end
647 return String(take!(out))
648 end
649
650 function readuntil(s::IO, delim::T; keep::Bool=false) where T
651 out = (T === UInt8 ? StringVector(0) : Vector{T}())
652 while !eof(s)
653 c = read(s, T)
654 if c == delim
655 keep && push!(out, c)
656 break
657 end
658 push!(out, c)
659 end
660 return out
661 end
662
663 # requires that indices for target are the integer unit range from firstindex to lastindex
664 # returns whether the delimiter was matched
665 # uses the Knuth–Morris–Pratt_algorithm, with the first and second cache entries unrolled
666 # For longer targets, the cache improves the big-O efficiency of scanning of sequences
667 # with repeated patterns
668 # Each cache entry tells us which index we should start the search at.
669 # We assume this is unlikely, so we only lazy-initialize as much of the cache as we need to use
670 # When we allocate the cache, we initialize it to 0 (and offset by the first index afterwards).
671 # Suppose target is:
672 # Index: 1245689
673 # Value: "aδcaδcx"
674 # We would set the cache to
675 # 0 0 0 1 2 3 4 0
676 # So after if we mismatch after the second aδc sequence,
677 # we can immediately jump back to index 5 (4 + 1).
678 function readuntil_vector!(io::IO, target::AbstractVector{T}, keep::Bool, out) where {T}
679 first = firstindex(target)
680 last = lastindex(target)
681 len = last - first + 1
682 if len < 1
683 return true
684 end
685 pos = 0 # array-offset
686 max_pos = 1 # array-offset in cache
687 local cache # will be lazy initialized when needed
688 output! = (isa(out, IO) ? write : push!)
689 while !eof(io)
690 c = read(io, T)
691 # Backtrack until the next target character matches what was found
692 while true
693 c1 = target[pos + first]
694 if c == c1
695 pos += 1
696 break
697 elseif pos == 0
698 break
699 elseif pos == 1
700 if !keep
701 output!(out, target[first])
702 end
703 pos = 0
704 else
705 # grow cache to contain up to `pos`
706 if !@isdefined(cache)
707 cache = zeros(Int, len)
708 end
709 while max_pos < pos
710 ci = target[max_pos + first]
711 b = max_pos
712 max_pos += 1
713 while b != 0
714 b = cache[b]
715 cb = target[b + first]
716 if ci == cb
717 cache[max_pos] = b + 1
718 break
719 end
720 end
721 end
722 # read new position from cache
723 pos1 = cache[pos]
724 if !keep
725 # and add the removed prefix from the target to the output
726 # if not always keeping the match
727 for b in 1:(pos - pos1)
728 output!(out, target[b - 1 + first])
729 end
730 end
731 pos = pos1
732 end
733 end
734 if keep || pos == 0
735 output!(out, c)
736 end
737 pos == len && return true
738 end
739 if !keep
740 # failed early without finishing the match,
741 # add the partial match to the output
742 # if not always keeping the match
743 for b in 1:pos
744 output!(out, target[b - 1 + first])
745 end
746 end
747 return false
748 end
749
750 function readuntil(io::IO, target::AbstractString; keep::Bool=false)
751 # small-string target optimizations
752 isempty(target) && return ""
753 c, rest = Iterators.peel(target)
754 if isempty(rest) && c <= '\x7f'
755 return readuntil_string(io, c % UInt8, keep)
756 end
757 # convert String to a utf8-byte-iterator
758 if !(target isa String) && !(target isa SubString{String})
759 target = String(target)
760 end
761 target = codeunits(target)::AbstractVector
762 return String(readuntil(io, target, keep=keep))
763 end
764
765 function readuntil(io::IO, target::AbstractVector{T}; keep::Bool=false) where T
766 out = (T === UInt8 ? StringVector(0) : Vector{T}())
767 readuntil_vector!(io, target, keep, out)
768 return out
769 end
770
771 """
772 readchomp(x)
773
774 Read the entirety of `x` as a string and remove a single trailing newline
775 if there is one. Equivalent to `chomp(read(x, String))`.
776
777 # Examples
778 ```jldoctest
779 julia> open("my_file.txt", "w") do io
780 write(io, "JuliaLang is a GitHub organization.\\nIt has many members.\\n");
781 end;
782
783 julia> readchomp("my_file.txt")
784 "JuliaLang is a GitHub organization.\\nIt has many members."
785
786 julia> rm("my_file.txt");
787 ```
788 """
789 readchomp(x) = chomp(read(x, String))
790
791 # read up to nb bytes into nb, returning # bytes read
792
793 """
794 readbytes!(stream::IO, b::AbstractVector{UInt8}, nb=length(b))
795
796 Read at most `nb` bytes from `stream` into `b`, returning the number of bytes read.
797 The size of `b` will be increased if needed (i.e. if `nb` is greater than `length(b)`
798 and enough bytes could be read), but it will never be decreased.
799 """
800 function readbytes!(s::IO, b::AbstractArray{UInt8}, nb=length(b))
801 @assert !has_offset_axes(b)
802 olb = lb = length(b)
803 nr = 0
804 while nr < nb && !eof(s)
805 a = read(s, UInt8)
806 nr += 1
807 if nr > lb
808 lb = nr * 2
809 resize!(b, lb)
810 end
811 b[nr] = a
812 end
813 if lb > olb
814 resize!(b, nr) # shrink to just contain input data if was resized
815 end
816 return nr
817 end
818
819 """
820 read(s::IO, nb=typemax(Int))
821
822 Read at most `nb` bytes from `s`, returning a `Vector{UInt8}` of the bytes read.
823 """
824 function read(s::IO, nb::Integer = typemax(Int))
825 # Let readbytes! grow the array progressively by default
826 # instead of taking of risk of over-allocating
827 b = Vector{UInt8}(undef, nb == typemax(Int) ? 1024 : nb)
828 nr = readbytes!(s, b, nb)
829 return resize!(b, nr)
830 end
831
832 read(s::IO, ::Type{String}) = String(read(s))
833 read(s::IO, T::Type) = error("The IO stream does not support reading objects of type $T.")
834
835 ## high-level iterator interfaces ##
836
837 struct EachLine{IOT <: IO}
838 stream::IOT
839 ondone::Function
840 keep::Bool
841 EachLine(stream::IO=stdin; ondone::Function=()->nothing, keep::Bool=false) =
842 new{typeof(stream)}(stream, ondone, keep)
843 end
844
845 """
846 eachline(io::IO=stdin; keep::Bool=false)
847 eachline(filename::AbstractString; keep::Bool=false)
848
849 Create an iterable `EachLine` object that will yield each line from an I/O stream
850 or a file. Iteration calls [`readline`](@ref) on the stream argument repeatedly with
851 `keep` passed through, determining whether trailing end-of-line characters are
852 retained. When called with a file name, the file is opened once at the beginning of
853 iteration and closed at the end. If iteration is interrupted, the file will be
854 closed when the `EachLine` object is garbage collected.
855
856 # Examples
857 ```jldoctest
858 julia> open("my_file.txt", "w") do io
859 write(io, "JuliaLang is a GitHub organization.\\n It has many members.\\n");
860 end;
861
862 julia> for line in eachline("my_file.txt")
863 print(line)
864 end
865 JuliaLang is a GitHub organization. It has many members.
866
867 julia> rm("my_file.txt");
868 ```
869 """
870 function eachline(stream::IO=stdin; keep::Bool=false)
871 EachLine(stream, keep=keep)::EachLine
872 end
873
874 function eachline(filename::AbstractString; keep::Bool=false)
875 s = open(filename)
876 EachLine(s, ondone=()->close(s), keep=keep)::EachLine
877 end
878
879 function iterate(itr::EachLine, state=nothing)
880 eof(itr.stream) && return (itr.ondone(); nothing)
881 (readline(itr.stream, keep=itr.keep), nothing)
882 end
883
884 eltype(::Type{<:EachLine}) = String
885
886 IteratorSize(::Type{<:EachLine}) = SizeUnknown()
887
888 # IOStream Marking
889 # Note that these functions expect that io.mark exists for
890 # the concrete IO type. This may not be true for IO types
891 # not in base.
892
893 """
894 mark(s)
895
896 Add a mark at the current position of stream `s`. Return the marked position.
897
898 See also [`unmark`](@ref), [`reset`](@ref), [`ismarked`](@ref).
899 """
900 function mark(io::IO)
901 io.mark = position(io)
902 end
903
904 """
905 unmark(s)
906
907 Remove a mark from stream `s`. Return `true` if the stream was marked, `false` otherwise.
908
909 See also [`mark`](@ref), [`reset`](@ref), [`ismarked`](@ref).
910 """
911 function unmark(io::IO)
912 !ismarked(io) && return false
913 io.mark = -1
914 return true
915 end
916
917 """
918 reset(s)
919
920 Reset a stream `s` to a previously marked position, and remove the mark. Return the
921 previously marked position. Throw an error if the stream is not marked.
922
923 See also [`mark`](@ref), [`unmark`](@ref), [`ismarked`](@ref).
924 """
925 function reset(io::T) where T<:IO
926 ismarked(io) || throw(ArgumentError("$(T) not marked"))
927 m = io.mark
928 seek(io, m)
929 io.mark = -1 # must be after seek, or seek may fail
930 return m
931 end
932
933 """
934 ismarked(s)
935
936 Return `true` if stream `s` is marked.
937
938 See also [`mark`](@ref), [`unmark`](@ref), [`reset`](@ref).
939 """
940 ismarked(io::IO) = io.mark >= 0
941
942 # Make sure all IO streams support flush, even if only as a no-op,
943 # to make it easier to write generic I/O code.
944
945 """
946 flush(stream)
947
948 Commit all currently buffered writes to the given stream.
949 """
950 flush(io::IO) = nothing
951
952 """
953 skipchars(predicate, io::IO; linecomment=nothing)
954
955 Advance the stream `io` such that the next-read character will be the first remaining for
956 which `predicate` returns `false`. If the keyword argument `linecomment` is specified, all
957 characters from that character until the start of the next line are ignored.
958
959 # Examples
960 ```jldoctest
961 julia> buf = IOBuffer(" text")
962 IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=8, maxsize=Inf, ptr=1, mark=-1)
963
964 julia> skipchars(isspace, buf)
965 IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=8, maxsize=Inf, ptr=5, mark=-1)
966
967 julia> String(readavailable(buf))
968 "text"
969 ```
970 """
971 function skipchars(predicate, io::IO; linecomment=nothing)
972 while !eof(io)
973 c = read(io, Char)
974 if c === linecomment
975 readline(io)
976 elseif !predicate(c)
977 skip(io, -codelen(c))
978 break
979 end
980 end
981 return io
982 end
983
984 """
985 countlines(io::IO; eol::AbstractChar = '\\n')
986
987 Read `io` until the end of the stream/file and count the number of lines. To specify a file
988 pass the filename as the first argument. EOL markers other than `'\\n'` are supported by
989 passing them as the second argument. The last non-empty line of `io` is counted even if it does not
990 end with the EOL, matching the length returned by [`eachline`](@ref) and [`readlines`](@ref).
991
992 # Examples
993 ```jldoctest
994 julia> io = IOBuffer("JuliaLang is a GitHub organization.\\n");
995
996 julia> countlines(io)
997 1
998
999 julia> io = IOBuffer("JuliaLang is a GitHub organization.");
1000
1001 julia> countlines(io)
1002 1
1003
1004 julia> countlines(io, eol = '.')
1005 0
1006 ```
1007 """
1008 function countlines(io::IO; eol::AbstractChar='\n')
1009 isascii(eol) || throw(ArgumentError("only ASCII line terminators are supported"))
1010 aeol = UInt8(eol)
1011 a = Vector{UInt8}(undef, 8192)
1012 nl = nb = 0
1013 while !eof(io)
1014 nb = readbytes!(io, a)
1015 @simd for i=1:nb
1016 @inbounds nl += a[i] == aeol
1017 end
1018 end
1019 if nb > 0 && a[nb] != aeol
1020 nl += 1 # final line is not terminated with eol
1021 end
1022 nl
1023 end
1024
1025 countlines(f::AbstractString; eol::AbstractChar = '\n') = open(io->countlines(io, eol = eol), f)::Int