Skip to content

Commit

Permalink
deprecate unsafe_wrap for String
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffBezanson committed Jan 4, 2017
1 parent 2ad2b41 commit 8ea9828
Show file tree
Hide file tree
Showing 10 changed files with 38 additions and 47 deletions.
4 changes: 0 additions & 4 deletions base/c.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,6 @@ pointer(p::Cwstring) = convert(Ptr{Cwchar_t}, p)
==(x::Union{Cstring,Cwstring}, y::Ptr) = pointer(x) == y
==(x::Ptr, y::Union{Cstring,Cwstring}) = x == pointer(y)

# here, not in pointer.jl, to avoid bootstrapping problems in coreimg.jl
unsafe_wrap(::Type{String}, p::Cstring, own::Bool=false) = unsafe_wrap(String, convert(Ptr{UInt8}, p), own)
unsafe_wrap(::Type{String}, p::Cstring, len::Integer, own::Bool=false) =
unsafe_wrap(String, convert(Ptr{UInt8}, p), len, own)
unsafe_string(s::Cstring) = unsafe_string(convert(Ptr{UInt8}, s))

# convert strings to String etc. to pass as pointers
Expand Down
13 changes: 13 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1483,4 +1483,17 @@ end
# Calling promote_op is likely a bad idea, so deprecate its convenience wrapper promote_eltype_op
@deprecate promote_eltype_op(op, As...) promote_op(op, map(eltype, As)...)

function unsafe_wrap(::Type{String}, p::Union{Ptr{UInt8},Ptr{Int8}}, len::Integer, own::Bool=false)
Base.depwarn("unsafe_wrap(String, ...) is deprecated; use `unsafe_string` instead.", :unsafe_wrap)
#ccall(:jl_array_to_string, Ref{String}, (Any,),
# ccall(:jl_ptr_to_array_1d, Vector{UInt8}, (Any, Ptr{UInt8}, Csize_t, Cint),
# Vector{UInt8}, p, len, own))
unsafe_string(p, len)
end
unsafe_wrap(::Type{String}, p::Union{Ptr{UInt8},Ptr{Int8}}, own::Bool=false) =
unsafe_wrap(String, p, ccall(:strlen, Csize_t, (Ptr{UInt8},), p), own)
unsafe_wrap(::Type{String}, p::Cstring, own::Bool=false) = unsafe_wrap(String, convert(Ptr{UInt8}, p), own)
unsafe_wrap(::Type{String}, p::Cstring, len::Integer, own::Bool=false) =
unsafe_wrap(String, convert(Ptr{UInt8}, p), len, own)

# End deprecations scheduled for 0.6
5 changes: 4 additions & 1 deletion base/fft/FFTW.jl
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,10 @@ sprint_plan_{T<:fftwDouble}(plan::FFTWPlan{T}) =
sprint_plan_{T<:fftwSingle}(plan::FFTWPlan{T}) =
ccall((:fftwf_sprint_plan,libfftwf), Ptr{UInt8}, (PlanPtr,), plan)
function sprint_plan(plan::FFTWPlan)
unsafe_wrap(String, sprint_plan_(plan), true)
p = sprint_plan_(plan)
str = unsafe_string(p)
Libc.free(p)
return str
end

function show{T,K,inplace}(io::IO, p::cFFTWPlan{T,K,inplace})
Expand Down
6 changes: 4 additions & 2 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -532,8 +532,10 @@ hex(n::BigInt, pad::Int) = base(16, n, pad)

function base(b::Integer, n::BigInt)
2 <= b <= 62 || throw(ArgumentError("base must be 2 ≤ base ≤ 62, got $b"))
p = ccall((:__gmpz_get_str,:libgmp), Ptr{UInt8}, (Ptr{UInt8}, Cint, Ptr{BigInt}), C_NULL, b, &n)
unsafe_wrap(String, p, true)
nd = ndigits(n, b)
str = Base._string_n(n < 0 ? nd+1 : nd)
ccall((:__gmpz_get_str,:libgmp), Ptr{UInt8}, (Ptr{UInt8}, Cint, Ptr{BigInt}), str, b, &n)
return str
end

function base(b::Integer, n::BigInt, pad::Integer)
Expand Down
4 changes: 3 additions & 1 deletion base/path.jl
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,9 @@ else # !windows
function realpath(path::AbstractString)
p = ccall(:realpath, Ptr{UInt8}, (Cstring, Ptr{UInt8}), path, C_NULL)
systemerror(:realpath, p == C_NULL)
return unsafe_wrap(String, p, true)
str = unsafe_string(p)
Libc.free(p)
return str
end
end # os-test

Expand Down
26 changes: 0 additions & 26 deletions base/pointer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,32 +93,6 @@ program, in the same manner as C.
unsafe_store!(p::Ptr{Any}, x::ANY, i::Integer=1) = pointerset(p, x, Int(i), 1)
unsafe_store!{T}(p::Ptr{T}, x, i::Integer=1) = pointerset(p, convert(T,x), Int(i), 1)

# unsafe pointer to string conversions (don't make a copy, unlike unsafe_string)
# (Cstring versions are in c.jl)
"""
unsafe_wrap(String, p::Ptr{UInt8}, [length,] own=false)
Wrap a pointer `p` to an array of bytes in a `String` object,
interpreting the bytes as UTF-8 encoded characters *without making a
copy*. The optional `length` argument indicates the length in bytes of
the pointer's data; if it is omitted, the data is assumed to be
NUL-terminated. The `own` argument optionally specifies whether Julia
should take ownership of the memory, calling `free` on the pointer
when the array is no longer referenced.
This function is labelled "unsafe" because it will crash if `p` is not
a valid memory address to data of the requested length.
See also [`unsafe_string`](@ref), which takes a pointer
and makes a copy of the data.
"""
unsafe_wrap(::Type{String}, p::Union{Ptr{UInt8},Ptr{Int8}}, len::Integer, own::Bool=false) =
ccall(:jl_array_to_string, Ref{String}, (Any,),
ccall(:jl_ptr_to_array_1d, Vector{UInt8}, (Any, Ptr{UInt8}, Csize_t, Cint),
Vector{UInt8}, p, len, own))
unsafe_wrap(::Type{String}, p::Union{Ptr{UInt8},Ptr{Int8}}, own::Bool=false) =
unsafe_wrap(String, p, ccall(:strlen, Csize_t, (Ptr{UInt8},), p), own)

# convert a raw Ptr to an object reference, and vice-versa
"""
unsafe_pointer_to_objref(p::Ptr)
Expand Down
3 changes: 0 additions & 3 deletions base/strings/string.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ Copy a string from the address of a C-style (NUL-terminated) string encoded as U
This function is labelled "unsafe" because it will crash if `p` is not
a valid memory address to data of the requested length.
See also [`unsafe_wrap(String, p, [length])`](@ref), which takes a pointer
and wraps a string object around it without making a copy.
"""
function unsafe_string(p::Union{Ptr{UInt8},Ptr{Int8}}, len::Integer)
p == C_NULL && throw(ArgumentError("cannot convert NULL to string"))
Expand Down
21 changes: 13 additions & 8 deletions base/strings/utf8proc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,19 @@ const UTF8PROC_STRIPMARK = (1<<13)

############################################################################

function utf8proc_map(s::String, flags::Integer)
p = Ref{Ptr{UInt8}}()
result = ccall(:utf8proc_map, Cssize_t,
(Ptr{UInt8}, Cssize_t, Ref{Ptr{UInt8}}, Cint),
s, sizeof(s), p, flags)
result < 0 && error(unsafe_string(ccall(:utf8proc_errmsg, Cstring,
(Cssize_t,), result)))
unsafe_wrap(String, p[], result, true)::String
utf8proc_error(result) = error(unsafe_string(ccall(:utf8proc_errmsg, Cstring, (Cssize_t,), result)))

function utf8proc_map(str::String, options::Integer)
nwords = ccall(:utf8proc_decompose, Int, (Ptr{UInt8}, Int, Ptr{UInt8}, Int, Cint),
str, sizeof(str), C_NULL, 0, options)
nwords < 0 && utf8proc_error(nwords)
buffer = Base.StringVector(nwords*4)
nwords = ccall(:utf8proc_decompose, Int, (Ptr{UInt8}, Int, Ptr{UInt8}, Int, Cint),
str, sizeof(str), buffer, nwords, options)
nwords < 0 && utf8proc_error(nwords)
nbytes = ccall(:utf8proc_reencode, Int, (Ptr{UInt8}, Int, Cint), buffer, nwords, options)
nbytes < 0 && utf8proc_error(nbytes)
return String(resize!(buffer, nbytes))
end

utf8proc_map(s::AbstractString, flags::Integer) = utf8proc_map(String(s), flags)
Expand Down
1 change: 0 additions & 1 deletion doc/src/stdlib/strings.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ Base.repr
Core.String(::AbstractString)
Base.transcode
Base.unsafe_string
Base.unsafe_wrap(::Type{String}, ::Union{Ptr{Int8}, Ptr{UInt8}}, ::Integer, ::Bool)
Base.codeunit(::AbstractString, ::Integer)
Base.ascii
Base.@r_str
Expand Down
2 changes: 1 addition & 1 deletion test/strings/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ end

cstrdup(s) = @static is_windows() ? ccall(:_strdup, Cstring, (Cstring,), s) : ccall(:strdup, Cstring, (Cstring,), s)
let p = cstrdup("hello")
@test unsafe_string(p) == "hello" == unsafe_wrap(String, cstrdup(p), true)
@test unsafe_string(p) == "hello"
Libc.free(p)
end

Expand Down

0 comments on commit 8ea9828

Please sign in to comment.