Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: ByteOrder types for io #3633

Merged
merged 2 commits into from
Jul 24, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions base/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,6 @@ end
show(io::IO, z::Complex) = complex_show(io, z, false)
showcompact(io::IO, z::Complex) = complex_show(io, z, true)

function read{T<:Real}(s::IO, ::Type{Complex{T}})
r = read(s,T)
i = read(s,T)
Complex{T}(r,i)
end
function write(s::IO, z::Complex)
write(s,real(z))
write(s,imag(z))
end


## singleton type for imaginary unit constant ##

Expand Down
6 changes: 5 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,10 @@ export
hton,
ltoh,
ntoh,
HostByteOrder,
ReverseByteOrder,
LittleByteOrder,
NetworkByteOrder,
mmap,
mmap_array,
mmap_bitarray,
Expand Down Expand Up @@ -1263,4 +1267,4 @@ export
@sprintf,
@deprecate,
@boundscheck,
@inbounds
@inbounds
100 changes: 77 additions & 23 deletions base/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,26 @@

## byte-order mark, ntoh & hton ##

abstract ByteOrder

type HostByteOrder <: ByteOrder
end

type ReverseByteOrder <: ByteOrder
end

const ENDIAN_BOM = reinterpret(Uint32,uint8([1:4]))[1]

if ENDIAN_BOM == 0x01020304
typealias NetworkByteOrder HostByteOrder
typealias LittleByteOrder ReverseByteOrder
ntoh(x) = identity(x)
hton(x) = identity(x)
ltoh(x) = bswap(x)
htol(x) = bswap(x)
elseif ENDIAN_BOM == 0x04030201
typealias NetworkByteOrder ReverseByteOrder
typealias LittleByteOrder HostByteOrder
ntoh(x) = bswap(x)
hton(x) = bswap(x)
ltoh(x) = identity(x)
Expand All @@ -30,28 +42,31 @@ write(s::IO, x::Uint8) = error(typeof(s)," does not support byte I/O")
write(io::IO, x) = throw(MethodError(write, (io, x)))
write(io::IO, xs...) = for x in xs write(io, x) end

if ENDIAN_BOM == 0x01020304
function write(s::IO, x::Integer)
sz = sizeof(x)
for n = sz:-1:1
write(s, uint8((x>>>((n-1)<<3))))
end
sz
function write(s::IO, x::Integer,::Type{NetworkByteOrder})
sz = sizeof(x)
for n = sz:-1:1
write(s, uint8((x>>>((n-1)<<3))))
end
else
function write(s::IO, x::Integer)
sz = sizeof(x)
for n = 1:sz
write(s, uint8((x>>>((n-1)<<3))))
end
sz
sz
end
function write(s::IO, x::Integer,::Type{LittleByteOrder})
sz = sizeof(x)
for n = 1:sz
write(s, uint8((x>>>((n-1)<<3))))
end
sz
end

write(s::IO, x::Bool) = write(s, uint8(x))
#write(s::IO, x::Float16) = write(s, reinterpret(Int16,x))
write(s::IO, x::Float32) = write(s, reinterpret(Int32,x))
write(s::IO, x::Float64) = write(s, reinterpret(Int64,x))
write(s::IO, x::Bool) = write(s, uint8(x))
#write{O<:ByteOrder}(s::IO, x::Float16, ::Type{O}) = write(s, reinterpret(Int16,x), O)
write{O<:ByteOrder}(s::IO, x::Float32, ::Type{O}) = write(s, reinterpret(Int32,x), O)
write{O<:ByteOrder}(s::IO, x::Float64, ::Type{O}) = write(s, reinterpret(Int64,x), O)
function write{O<:ByteOrder}(s::IO, z::Complex, ::Type{O})
write(s,real(z),O)
write(s,imag(z),O)
end

write(s::IO, x::Number) = write(s, x, HostByteOrder)

function write(s::IO, a::AbstractArray)
nb = 0
Expand All @@ -60,6 +75,14 @@ function write(s::IO, a::AbstractArray)
end
nb
end
function write{O<:ByteOrder}(s::IO, a::AbstractArray, ::Type{O})
nb = 0
for i = 1:length(a)
nb += write(s, a[i],O)
end
nb
end


function write(s::IO, c::Char)
if c < 0x80
Expand Down Expand Up @@ -88,32 +111,61 @@ end
# all subtypes should implement this
read(s::IO, x::Type{Uint8}) = error(typeof(s)," does not support byte I/O")

function read{T <: Integer}(s::IO, ::Type{T})
function read{T <: Integer}(s::IO, ::Type{T},::Type{LittleByteOrder})
x = zero(T)
for n = 1:sizeof(x)
x |= (convert(T,read(s,Uint8))<<((n-1)<<3))
end
return x
end

function read{T <: Integer}(s::IO, ::Type{T},::Type{NetworkByteOrder})
x = zero(T)
for n = sizeof(x):-1:1
x |= (convert(T,read(s,Uint8))<<((n-1)<<3))
end
return x
end

read(s::IO, ::Type{Bool}) = (read(s,Uint8)!=0)
read(s::IO, ::Type{Float32}) = box(Float32,unbox(Int32,read(s,Int32)))
read(s::IO, ::Type{Float64}) = box(Float64,unbox(Int64,read(s,Int64)))
read{O<:ByteOrder}(s::IO, ::Type{Float32}, ::Type{O}) = reinterpret(Float32,read(s,Int32,O))
read{O<:ByteOrder}(s::IO, ::Type{Float64}, ::Type{O}) = reinterpret(Float64,read(s,Int64,O))
function read{T<:Real,O<:ByteOrder}(s::IO, ::Type{Complex{T}}, ::Type{O})
r = read(s,T,O)
i = read(s,T,O)
Complex{T}(r,i)
end

read{N<:Number}(s::IO, ::Type{N}) = read(s,N,HostByteOrder)


read{T}(s::IO, t::Type{T}, d1::Int, dims::Int...) =
read(s, t, tuple(d1,dims...))
read{T}(s::IO, t::Type{T}, d1::Integer, dims::Integer...) =
read(s, t, map(int,tuple(d1,dims...)))

read{T}(s::IO, ::Type{T}, dims::Dims) = read(s, Array(T, dims))

function read{T}(s::IO, a::Array{T})
for i = 1:length(a)
a[i] = read(s, T)
end
return a
end

read{T,O<:ByteOrder}(s::IO, t::Type{T}, ::Type{O}, d1::Int, dims::Int...) =
read(s, t, O, tuple(d1,dims...))
read{T,O<:ByteOrder}(s::IO, t::Type{T}, ::Type{O}, d1::Integer, dims::Integer...) =
read(s, t, O, map(int,tuple(d1,dims...)))
read{T,O<:ByteOrder}(s::IO, ::Type{T}, ::Type{O}, dims::Dims) = read(s, Array(T, dims), O)

function read{T,O<:ByteOrder}(s::IO, a::Array{T}, ::Type{O})
for i = 1:length(a)
a[i] = read(s, T, O)
end
return a
end



function read(s::IO, ::Type{Char})
ch = read(s, Uint8)
if ch < 0x80
Expand Down Expand Up @@ -495,4 +547,6 @@ end
# BitArray I/O

write(s::IO, B::BitArray) = write(s, B.chunks)
write{O<:ByteOrder}(s::IO, B::BitArray, ::Type{O}) = write(s, B.chunks, O)
read(s::IO, B::BitArray) = read(s, B.chunks)
read{O<:ByteOrder}(s::IO, B::BitArray, ::Type{O}) = read(s, B.chunks, O)
Loading