Skip to content

Commit e7a7237

Browse files
committed
export and document transcode from JuliaLang#16974, add transcode(String, x) and transcode(T, ::String) convenience methods
1 parent 5331948 commit e7a7237

File tree

8 files changed

+29
-9
lines changed

8 files changed

+29
-9
lines changed

base/c.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,21 @@ end
121121

122122
# transcoding between data in UTF-8 and UTF-16 for Windows APIs
123123

124+
"""
125+
transcode(T, src)
126+
127+
Convert string data between Unicode encodings. `src` is either a
128+
`String` or an `Vector{UIntXX}` of UTF-XX code units, where
129+
`XX` is 8 or 16. `T` indicates the encoding of the return value:
130+
`String` to return a (UTF-8 encoded) `String` or `UIntXX`
131+
to return a `Vector{UIntXX}` of the UTF-`XX` data.
132+
"""
133+
function transcode end
134+
124135
transcode{T<:Union{UInt8,UInt16}}(::Type{T}, src::Vector{T}) = src
125136
transcode(::Type{Int32}, src::Vector{UInt32}) = reinterpret(Int32, src)
137+
transcode(T, src::String) = transcode(T, src.data)
138+
transcode(::Type{String}, src) = String(transcode(UInt8, src))
126139

127140
function transcode(::Type{UInt16}, src::Vector{UInt8})
128141
dst = UInt16[]

base/env.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function access_env(onError::Function, str::AbstractString)
1919
error(string("getenv: ", str, ' ', len, "-1 != ", ret, ": ", Libc.FormatMessage()))
2020
end
2121
pop!(val) # NUL
22-
return String(transcode(UInt8, val))
22+
return transcode(String, val)
2323
end
2424

2525
function _setenv(svar::AbstractString, sval::AbstractString, overwrite::Bool=true)
@@ -97,7 +97,7 @@ function next(hash::EnvHash, block::Tuple{Ptr{UInt16},Ptr{UInt16}})
9797
len = ccall(:wcslen, UInt, (Ptr{UInt16},), pos)
9898
buf = Array{UInt16}(len)
9999
unsafe_copy!(pointer(buf), pos, len)
100-
env = String(transcode(UInt8, buf))
100+
env = transcode(String, buf)
101101
m = match(r"^(=?[^=]+)=(.*)$"s, env)
102102
if m === nothing
103103
error("malformed environment entry: $env")

base/exports.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,7 @@ export
877877
strip,
878878
strwidth,
879879
summary,
880+
transcode,
880881
ucfirst,
881882
unescape_string,
882883
uppercase,

base/file.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ function tempdir()
203203
error("GetTempPath failed: $(Libc.FormatMessage())")
204204
end
205205
resize!(temppath,lentemppath)
206-
return String(transcode(UInt8, temppath))
206+
return transcode(String, temppath)
207207
end
208208
tempname(uunique::UInt32=UInt32(0)) = tempname(tempdir(), uunique)
209209
const temp_prefix = cwstring("jl_")
@@ -216,7 +216,7 @@ function tempname(temppath::AbstractString,uunique::UInt32)
216216
error("GetTempFileName failed: $(Libc.FormatMessage())")
217217
end
218218
resize!(tname,lentname)
219-
return String(transcode(UInt8, tname))
219+
return transcode(String, tname)
220220
end
221221
function mktemp(parent=tempdir())
222222
filename = tempname(parent, UInt32(0))

base/interactiveutil.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ elseif is_windows()
150150
len = 0
151151
while unsafe_load(plock, len+1) != 0; len += 1; end
152152
# get Vector{UInt16}, transcode data to UTF-8, make a String of it
153-
s = String(transcode(UInt8, unsafe_wrap(Array, plock, len)))
153+
s = transcode(String, unsafe_wrap(Array, plock, len))
154154
systemerror(:GlobalUnlock, 0==ccall((:GlobalUnlock, "kernel32"), stdcall, Cint, (Ptr{UInt16},), plock))
155155
return s
156156
end

base/libc.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ if is_windows()
277277
buf = Array{UInt16}(len)
278278
unsafe_copy!(pointer(buf), p, len)
279279
ccall(:LocalFree,stdcall,Ptr{Void},(Ptr{Void},),p)
280-
return String(transcode(UInt8, buf))
280+
return transcode(String, buf)
281281
end
282282
end
283283

base/path.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ function realpath(path::AbstractString)
136136
systemerror(:realpath, n == 0)
137137
x = n < length(buf) # is the buffer big enough?
138138
resize!(buf, n) # shrink if x, grow if !x
139-
x && return String(transcode(UInt8, buf))
139+
x && return transcode(String, buf)
140140
end
141141
end
142142

@@ -150,7 +150,7 @@ function longpath(path::AbstractString)
150150
systemerror(:longpath, n == 0)
151151
x = n < length(buf) # is the buffer big enough?
152152
resize!(buf, n) # shrink if x, grow if !x
153-
x && return String(transcode(UInt8, buf))
153+
x && return transcode(String, buf)
154154
end
155155
end
156156

test/misc.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ whos(IOBuffer(), Tmp14173) # warm up
209209
@test @allocated(whos(IOBuffer(), Tmp14173)) < 10000
210210

211211
## test conversion from UTF-8 to UTF-16 (for Windows APIs)
212-
import Base.Libc: transcode
213212

214213
# empty arrays
215214
@test transcode(UInt16, UInt8[]) == UInt16[]
@@ -376,6 +375,13 @@ for (X,Y,Z) in ((V16,V16,V16), (I16,V16,I16), (V16,I16,V16), (V16,V16,I16), (I16
376375
end
377376
end
378377

378+
let s = "abcα🐨\0x\0"
379+
for T in (UInt8, UInt16)
380+
@test transcode(T, s) == transcode(T, s.data)
381+
@test transcode(String, transcode(T, s)) == s
382+
end
383+
end
384+
379385
# clipboard functionality
380386
if is_windows()
381387
for str in ("Hello, world.", "∀ x ∃ y", "")

0 commit comments

Comments
 (0)