Skip to content
4 changes: 2 additions & 2 deletions base/filesystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ import .Base:
bytesavailable, position, read, read!, readavailable, seek, seekend, show,
skip, stat, unsafe_read, unsafe_write, write, transcode, uv_error,
setup_stdio, rawhandle, OS_HANDLE, INVALID_OS_HANDLE, windowserror, filesize,
isexecutable, isreadable, iswritable
isexecutable, isreadable, iswritable, MutableDenseArrayType

import .Base.RefValue

Expand Down Expand Up @@ -309,7 +309,7 @@ bytesavailable(f::File) = max(0, filesize(f) - position(f)) # position can be >

eof(f::File) = bytesavailable(f) == 0

function readbytes!(f::File, b::Array{UInt8}, nb=length(b))
function readbytes!(f::File, b::MutableDenseArrayType{UInt8}, nb=length(b))
nr = min(nb, bytesavailable(f))
if length(b) < nr
resize!(b, nr)
Expand Down
6 changes: 3 additions & 3 deletions base/iobuffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ function read_sub(from::GenericIOBuffer, a::AbstractArray{T}, offs, nel) where T
if offs+nel-1 > length(a) || offs < 1 || nel < 0
throw(BoundsError())
end
if isbitstype(T) && isa(a,Array)
if isa(a, MutableDenseArrayType{UInt8})
nb = UInt(nel * sizeof(T))
GC.@preserve a unsafe_read(from, pointer(a, offs), nb)
else
Expand Down Expand Up @@ -548,8 +548,8 @@ end
return sizeof(UInt8)
end

readbytes!(io::GenericIOBuffer, b::Array{UInt8}, nb=length(b)) = readbytes!(io, b, Int(nb))
function readbytes!(io::GenericIOBuffer, b::Array{UInt8}, nb::Int)
readbytes!(io::GenericIOBuffer, b::MutableDenseArrayType{UInt8}, nb=length(b)) = readbytes!(io, b, Int(nb))
function readbytes!(io::GenericIOBuffer, b::MutableDenseArrayType{UInt8}, nb::Int)
nr = min(nb, bytesavailable(io))
if length(b) < nr
resize!(b, nr)
Expand Down
13 changes: 3 additions & 10 deletions base/iostream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,7 @@ function copyuntil(out::IOStream, s::IOStream, delim::UInt8; keep::Bool=false)
return out
end

function readbytes_all!(s::IOStream,
b::Union{Array{UInt8}, FastContiguousSubArray{UInt8,<:Any,<:Array{UInt8}}},
nb::Integer)
function readbytes_all!(s::IOStream, b::MutableDenseArrayType{UInt8}, nb::Integer)
olb = lb = length(b)
nr = 0
let l = s._dolock, slock = s.lock
Expand Down Expand Up @@ -516,9 +514,7 @@ function readbytes_all!(s::IOStream,
return nr
end

function readbytes_some!(s::IOStream,
b::Union{Array{UInt8}, FastContiguousSubArray{UInt8,<:Any,<:Array{UInt8}}},
nb::Integer)
function readbytes_some!(s::IOStream, b::MutableDenseArrayType{UInt8}, nb::Integer)
olb = length(b)
if nb > olb
resize!(b, nb)
Expand Down Expand Up @@ -547,10 +543,7 @@ requested bytes, until an error or end-of-file occurs. If `all` is `false`, at m
`read` call is performed, and the amount of data returned is device-dependent. Note that not
all stream types support the `all` option.
"""
function readbytes!(s::IOStream,
b::Union{Array{UInt8}, FastContiguousSubArray{UInt8,<:Any,<:Array{UInt8}}},
nb=length(b);
all::Bool=true)
function readbytes!(s::IOStream, b::MutableDenseArrayType{UInt8}, nb=length(b); all::Bool=true)
return all ? readbytes_all!(s, b, nb) : readbytes_some!(s, b, nb)
end

Expand Down
12 changes: 11 additions & 1 deletion base/strings/search.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ function findnext(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:AbstractChar}
end
end

# Note: Currently, CodeUnits <: DenseVector, which makes this union redundant w.r.t
# DenseArrayType{UInt8}, but this is a bug, and may be removed in future versions
# of Julia. See #54002
const DenseBytes = Union{
<:DenseArrayType{UInt8},
CodeUnits{UInt8, <:Union{String, SubString{String}}},
}

const ByteArray = Union{DenseBytes, DenseArrayType{Int8}}

findfirst(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:Union{Int8,UInt8}}, a::ByteArray) =
nothing_sentinel(_search(a, pred.x))

Expand All @@ -38,7 +48,7 @@ findnext(pred::Fix2{<:Union{typeof(isequal),typeof(==)},<:Union{Int8,UInt8}}, a:
findfirst(::typeof(iszero), a::ByteArray) = nothing_sentinel(_search(a, zero(UInt8)))
findnext(::typeof(iszero), a::ByteArray, i::Integer) = nothing_sentinel(_search(a, zero(UInt8), i))

function _search(a::Union{String,SubString{String},ByteArray}, b::Union{Int8,UInt8}, i::Integer = 1)
function _search(a::Union{String,SubString{String},<:ByteArray}, b::Union{Int8,UInt8}, i::Integer = 1)
if i < 1
throw(BoundsError(a, i))
end
Expand Down
2 changes: 0 additions & 2 deletions base/strings/string.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ function Base.showerror(io::IO, exc::StringIndexError)
end
end

const ByteArray = Union{CodeUnits{UInt8,String}, Vector{UInt8},Vector{Int8}, FastContiguousSubArray{UInt8,1,CodeUnits{UInt8,String}}, FastContiguousSubArray{UInt8,1,Vector{UInt8}}, FastContiguousSubArray{Int8,1,Vector{Int8}}}

@inline between(b::T, lo::T, hi::T) where {T<:Integer} = (lo ≤ b) & (b ≤ hi)

"""
Expand Down
18 changes: 18 additions & 0 deletions base/subarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,24 @@ FastContiguousSubArray{T,N,P,I<:Union{Tuple{Union{Slice, AbstractUnitRange}, Var
@inline _reindexlinear(V::FastContiguousSubArray, i::Int) = V.offset1 + i
@inline _reindexlinear(V::FastContiguousSubArray, i::AbstractUnitRange{Int}) = V.offset1 .+ i

"""
An internal type representing arrays stored contiguously in memory.
"""
const DenseArrayType{T,N} = Union{
DenseArray{T,N},
<:FastContiguousSubArray{T,N,<:DenseArray},
}

"""
An internal type representing mutable arrays stored contiguously in memory.
"""
const MutableDenseArrayType{T,N} = Union{
Array{T, N},
Memory{T},
FastContiguousSubArray{T,N,<:Array},
FastContiguousSubArray{T,N,<:Memory}
}

# parents of FastContiguousSubArrays may support fast indexing with AbstractUnitRanges,
# so we may just forward the indexing to the parent
# This may only be done for non-offset ranges, as the result would otherwise have offset axes
Expand Down
4 changes: 3 additions & 1 deletion base/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,10 @@ unsafe_crc32c(a, n, crc) = ccall(:jl_crc32c, UInt32, (UInt32, Ptr{UInt8}, Csize_

_crc32c(a::NTuple{<:Any, UInt8}, crc::UInt32=0x00000000) =
unsafe_crc32c(Ref(a), length(a) % Csize_t, crc)
_crc32c(a::Union{Array{UInt8},FastContiguousSubArray{UInt8,N,<:Array{UInt8}} where N}, crc::UInt32=0x00000000) =

function _crc32c(a::DenseBytes, crc::UInt32=0x00000000)
unsafe_crc32c(a, length(a) % Csize_t, crc)
end

function _crc32c(s::Union{String, SubString{String}}, crc::UInt32=0x00000000)
unsafe_crc32c(s, sizeof(s) % Csize_t, crc)
Expand Down
6 changes: 5 additions & 1 deletion stdlib/CRC32c/src/CRC32c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ See [`CRC32c.crc32c`](@ref) for more information.
module CRC32c

import Base.FastContiguousSubArray
import Base: DenseBytes

export crc32c

Expand Down Expand Up @@ -35,7 +36,10 @@ but note that the result may be endian-dependent.
function crc32c end


crc32c(a::Union{Array{UInt8},FastContiguousSubArray{UInt8,N,<:Array{UInt8}} where N}, crc::UInt32=0x00000000) = Base._crc32c(a, crc)
function crc32c(a::DenseBytes, crc::UInt32=0x00000000)
Base._crc32c(a, crc)
end

crc32c(s::Union{String, SubString{String}}, crc::UInt32=0x00000000) = Base._crc32c(s, crc)

"""
Expand Down