diff --git a/src/FlatBuffers/table.jl b/src/FlatBuffers/table.jl index a17d1cd0..a430ea50 100644 --- a/src/FlatBuffers/table.jl +++ b/src/FlatBuffers/table.jl @@ -100,18 +100,23 @@ function vector(t::Table, off) return x + sizeof(UOffsetT) end -struct Array{T,S,TT} <: AbstractVector{T} +struct Array{T,S,TT,D<:AbstractVector{S}} <: AbstractVector{T} _tab::TT pos::Int64 - data::Vector{S} + data::D end function Array{T}(t::Table, off) where {T} a = vector(t, off) S = T <: Table ? UOffsetT : T <: Struct ? NTuple{structsizeof(T),UInt8} : T ptr = convert(Ptr{S}, pointer(bytes(t), a + 1)) - data = unsafe_wrap(Base.Array, ptr, vectorlen(t, off)) - return Array{T,S,typeof(t)}(t, a, data) + len = vectorlen(t, off) + data = if UInt(ptr) % Base.datatype_alignment(S) == 0 + unsafe_wrap(Base.Array, ptr, len) + else + reinterpret(S, @view bytes(t)[(a + 1):(a + len * sizeof(S))]) + end + return Array{T,S,typeof(t),typeof(data)}(t, a, data) end function structsizeof end diff --git a/src/metadata/Message.jl b/src/metadata/Message.jl index 0e494394..126297f8 100644 --- a/src/metadata/Message.jl +++ b/src/metadata/Message.jl @@ -101,7 +101,7 @@ function Base.getproperty(x::RecordBatch, field::Symbol) elseif field === :variadicBufferCounts o = FlatBuffers.offset(x, 12) if o != 0 - return FlatBuffers.Array{Int32}(x, o) + return FlatBuffers.Array{Int64}(x, o) end end return nothing diff --git a/test/runtests.jl b/test/runtests.jl index 4f7d28b2..a19b4a3a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1107,6 +1107,22 @@ end joinpath(dirname(pathof(Arrow)), "../test/reject_reason_trimmed.arrow"), ) @test t.reject_reason[end] == "POST_ONLY" + + # RecordBatch.variadicBufferCounts uses 64-bit integers in the Arrow spec + FB = Arrow.FlatBuffers + b = FB.Builder(64) + FB.startvector!(b, sizeof(Int64), 3, sizeof(Int64)) + for cnt in Iterators.reverse(Int64[0, 7, 0]) + FB.prepend!(b, cnt) + end + varcounts = FB.endvector!(b, 3) + FB.startobject!(b, 5) + FB.prependoffsetslot!(b, 4, varcounts, 0) # slot 4 (offset 12) = variadicBufferCounts + FB.finish!(b, Arrow.Meta.recordBatchEnd(b)) + + rb = FB.getrootas(Arrow.Meta.RecordBatch, Vector(FB.finishedbytes(b)), 0) + @test eltype(rb.variadicBufferCounts) === Int64 + @test collect(rb.variadicBufferCounts) == Int64[0, 7, 0] end end # @testset "misc"