Skip to content

Commit 8393eee

Browse files
committed
Add peek(io, T)
1 parent 14343a3 commit 8393eee

File tree

12 files changed

+40
-18
lines changed

12 files changed

+40
-18
lines changed

base/essentials.jl

+8-2
Original file line numberDiff line numberDiff line change
@@ -787,9 +787,9 @@ ismissing(::Missing) = true
787787
function popfirst! end
788788

789789
"""
790-
peek(stream)
790+
peek(stream[, T=UInt8])
791791
792-
Read and return the next value from a stream without advancing the current position
792+
Read and return a value of type `T` from a stream without advancing the current position
793793
in the stream.
794794
795795
# Examples
@@ -802,7 +802,13 @@ julia> peek(b)
802802
803803
julia> position(b)
804804
0
805+
806+
julia> peek(b, Char)
807+
'j': ASCII/Unicode U+006A (category Ll: Letter, lowercase)
805808
```
809+
810+
!!! compat "Julia 1.5"
811+
The method which accepts a type requires Julia 1.5 or later.
806812
"""
807813
function peek end
808814

base/io.jl

+4-2
Original file line numberDiff line numberDiff line change
@@ -251,14 +251,16 @@ function unsafe_read(s::IO, p::Ptr{UInt8}, n::UInt)
251251
nothing
252252
end
253253

254-
function peek(s::IO)
254+
function peek(s::IO, ::Type{T}) where T
255255
mark(s)
256-
try read(s, UInt8)
256+
try read(s, T)
257257
finally
258258
reset(s)
259259
end
260260
end
261261

262+
peek(s) = peek(s, UInt8)
263+
262264
# Generic `open` methods
263265

264266
"""

base/iobuffer.jl

+8-3
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ function unsafe_read(from::GenericIOBuffer, p::Ptr{UInt8}, nb::UInt)
172172
nothing
173173
end
174174

175-
function read(from::GenericIOBuffer, T::Union{Type{Int16},Type{UInt16},Type{Int32},Type{UInt32},Type{Int64},Type{UInt64},Type{Int128},Type{UInt128},Type{Float16},Type{Float32},Type{Float64}})
175+
function peek(from::GenericIOBuffer, T::Union{Type{Int16},Type{UInt16},Type{Int32},Type{UInt32},Type{Int64},Type{UInt64},Type{Int128},Type{UInt128},Type{Float16},Type{Float32},Type{Float64}})
176176
from.readable || _throw_not_readable()
177177
avail = bytesavailable(from)
178178
nb = sizeof(T)
@@ -183,7 +183,12 @@ function read(from::GenericIOBuffer, T::Union{Type{Int16},Type{UInt16},Type{Int3
183183
ptr::Ptr{T} = pointer(from.data, from.ptr)
184184
x = unsafe_load(ptr)
185185
end
186-
from.ptr += nb
186+
return x
187+
end
188+
189+
function read(from::GenericIOBuffer, T::Union{Type{Int16},Type{UInt16},Type{Int32},Type{UInt32},Type{Int64},Type{UInt64},Type{Int128},Type{UInt128},Type{Float16},Type{Float32},Type{Float64}})
190+
x = peek(from, T)
191+
from.ptr += sizeof(T)
187192
return x
188193
end
189194

@@ -216,7 +221,7 @@ end
216221
return byte
217222
end
218223

219-
function peek(from::GenericIOBuffer)
224+
function peek(from::GenericIOBuffer, ::Type{UInt8})
220225
from.readable || _throw_not_readable()
221226
if from.ptr > from.size
222227
throw(EOFError())

base/secretbuffer.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ bytesavailable(io::SecretBuffer) = io.size - io.ptr + 1
154154
position(io::SecretBuffer) = io.ptr-1
155155
eof(io::SecretBuffer) = io.ptr > io.size
156156
isempty(io::SecretBuffer) = io.size == 0
157-
function peek(io::SecretBuffer)
157+
function peek(io::SecretBuffer, ::Type{UInt8})
158158
eof(io) && throw(EOFError())
159159
return io.data[io.ptr]
160160
end

base/stream.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1193,9 +1193,9 @@ unmark(x::LibuvStream) = unmark(x.buffer)
11931193
reset(x::LibuvStream) = reset(x.buffer)
11941194
ismarked(x::LibuvStream) = ismarked(x.buffer)
11951195

1196-
function peek(s::LibuvStream)
1196+
function peek(s::LibuvStream, ::Type{T}) where T
11971197
mark(s)
1198-
try read(s, UInt8)
1198+
try read(s, T)
11991199
finally
12001200
reset(s)
12011201
end

stdlib/Markdown/src/Common/block.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function paragraph(stream::IO, md::MD)
1919
while !eof(stream)
2020
char = read(stream, Char)
2121
if char == '\n' || char == '\r'
22-
char == '\r' && !eof(stream) && Char(peek(stream)) == '\n' && read(stream, Char)
22+
char == '\r' && !eof(stream) && peek(stream, Char) == '\n' && read(stream, Char)
2323
if prev_char == '\\'
2424
write(buffer, '\n')
2525
elseif blankline(stream) || parse(stream, md, breaking = true)

stdlib/Markdown/src/Julia/interp.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ end
99

1010
function interpinner(stream::IO, greedy = false)
1111
startswith(stream, '$') || return
12-
(eof(stream) || Char(peek(stream)) in whitespace) && return
12+
(eof(stream) || peek(stream, Char) in whitespace) && return
1313
try
1414
return _parse(stream::IOBuffer, greedy = greedy)
1515
catch e

stdlib/Markdown/src/parse/parse.jl

+1-3
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,7 @@ function parseinline(stream::IO, md::MD, config::Config)
5353
content = []
5454
buffer = IOBuffer()
5555
while !eof(stream)
56-
# FIXME: this is broken if we're looking for non-ASCII
57-
# characters because peek only returns a single byte.
58-
char = Char(peek(stream))
56+
char = peek(stream, Char)
5957
if haskey(config.inner, char) &&
6058
(inner = parseinline(stream, md, config.inner[char])) !== nothing
6159
c = String(take!(buffer))

stdlib/Markdown/src/parse/util.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const whitespace = " \t\r"
1414
Skip any leading whitespace. Returns io.
1515
"""
1616
function skipwhitespace(io::IO; newlines = true)
17-
while !eof(io) && (Char(peek(io)) in whitespace || (newlines && peek(io) == UInt8('\n')))
17+
while !eof(io) && (peek(io, Char) in whitespace || (newlines && peek(io) == UInt8('\n')))
1818
read(io, Char)
1919
end
2020
return io
@@ -180,7 +180,7 @@ function parse_inline_wrapper(stream::IO, delimiter::AbstractString; rep = false
180180
startswith(stream, delimiter^n) || return nothing
181181
while startswith(stream, delimiter); n += 1; end
182182
!rep && n > nmin && return nothing
183-
!eof(stream) && Char(peek(stream)) in whitespace && return nothing
183+
!eof(stream) && peek(stream, Char) in whitespace && return nothing
184184

185185
buffer = IOBuffer()
186186
while !eof(stream)

stdlib/REPL/src/REPL.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ function hist_from_file(hp, file, path)
542542
while !isempty(line)
543543
push!(lines, chomp(line[2:end]))
544544
eof(file) && break
545-
ch = Char(peek(file))
545+
ch = peek(file, Char)
546546
ch == ' ' && error(munged_history_message(path), countlines)
547547
ch != '\t' && break
548548
line = hist_getline(file)

test/iobuffer.jl

+9
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,12 @@ end
332332
@test readline(b) == "Goodbye!"
333333
close(b)
334334
end
335+
336+
@testset "peek(::GenericIOBuffer)" begin
337+
io = Base.GenericIOBuffer(UInt8[], true, true, false, true, typemax(Int))
338+
write(io, "こんにちは")
339+
@test peek(io) == 0xe3
340+
@test peek(io, Char) == ''
341+
@test peek(io, Int32) == -476872221
342+
close(io)
343+
end

test/secretbuffer.jl

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ using Test
1111
@test read(secret, String) == str
1212
seekstart(secret)
1313

14+
@test peek(secret) == 0x66
15+
1416
@test shred!(secret) === secret
1517
@test read(secret, String) == ""
1618
@test str == "foobar"

0 commit comments

Comments
 (0)