I have a packed structure of data in a binary stream that I wish to
read in julia. I defined the type struct and then added a read method
to dispatch for that type:
struct MyStruct
A::Int16
B::Int16
C::Int64
D::Int16
E::Int16
F::UInt32
end
import Base.read
function read(s::IO, ::Type{Caen_v20_0x1})
a = Base.read(s, Int16)
b = Base.read(s, Int16)
c = Base.read(s, Int64)
d = Base.read(s, Int16)
e = Base.read(s, Int16)
f = Base.read(s, UInt32)
MyStruct(a,b,c,d,e,f)
end
With this I can use read to read a single MyStruct value.
val = read(io,MyStruct) or in a loop with
vMyStruct = Vector{MyStruct}(undef,10)
for i in eachindex(vMyStruct)
vMyStruct[i] = read(io,eltype(vMyStruct))
end
However, when I use read!(io,vMyStruct) the result is not
equivalent. I looked at the code for read! and it appears
that the IO is just an unsafe_read of the binary stream and
not repeated use of the read method as defined.
Looking at the code for read in base it seems that the looping
over the read method is in there but that the check to see if an
unsafe_read would give the correct result may not be correct.
From io.jl in base:
function read!(s::IO, a::AbstractArray{T}) where T
if isbitstype(T) && (a isa Array || a isa FastContiguousSubArray{T,<:Any,<:Array{T}})
GC.@preserve a unsafe_read(s, pointer(a), sizeof(a))
else
for i in eachindex(a)
a[i] = read(s, T)
end
end
return a
end
It seems like the FastContiguousSubArray test maybe should be
&& instead of || which might make the hand loop with eachindex
unneccessary.
I vaguely remember this working the last time I worked with the I/O
but maybe I am misremembering things…
Is this the intended operation for read! in this case?