MsgPack.jl icon indicating copy to clipboard operation
MsgPack.jl copied to clipboard

Unable to add in support for Complex values as expanded into arrays

Open synthfi opened this issue 2 years ago • 0 comments

I'm trying to serialize and deserialize complex values in a similar fashion to how it is done with Rust's num-complex + rmp-serde packages

  • expanding ComplexF32 to an array of Float32
  • expanding ComplexF64 to an array of Float64

As an example, num-complex in Rust will generate the following bytes for 1.1 + 0.1im:
[0x92, 0xcb, 0x3f, 0xf1, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a, 0xcb, 0x3f, 0xb9, 0x99, 0x99, 0x99, 0x99, 0x99, 0x9a]

I'm trying to do the same with Julia with the following piece of code

MsgPack.msgpack_type(::Type{Complex{Float32}}) = MsgPack.ArrayType()
MsgPack.msgpack_type(::Type{Complex{Float64}}) = MsgPack.ArrayType()
MsgPack.to_msgpack(::MsgPack.ArrayType, arr::Complex{Float32}) = [real(arr), imag(arr)]
MsgPack.to_msgpack(::MsgPack.ArrayType, arr::Complex{Float64}) = [real(arr), imag(arr)]
MsgPack.from_msgpack(::Type{Complex{Float32}}, arr::Vector{Float32}) = Complex{Float32}(arr[1], arr[2])
MsgPack.from_msgpack(::Type{Complex{Float64}}, arr::Vector{Float64}) = Complex{Float64}(arr[1], arr[2])

I can successfully generate the same bytes with this

julia> val
1.1 + 0.1im
julia> pack(val)
19-element Vector{UInt8}:
 0x92
 0xcb
.... (more stuff here)
julia> unpack(pack(val))
2-element Vector{Any}:
 1.1
 0.1

but unpack(pack(val), ComplexF64) fails with this

julia> unpack(pack(val), ComplexF64)
ERROR: invalid byte 0xcb encountered in IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=19, maxsize=Inf, ptr=3, mark=-1) attempting to read a MsgPack MsgPack.ArrayType() into a Julia ComplexF64 at position 2
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:33
  [2] invalid_unpack(io::IOBuffer, byte::UInt8, m::MsgPack.ArrayType, T::Type)
    @ MsgPack ~/.julia/packages/MsgPack/pN9xd/src/unpack.jl:543
  [3] unpack_type(io::IOBuffer, byte::UInt8, t::MsgPack.ArrayType, ::Type{ComplexF64}; strict::Tuple{})
    @ MsgPack ~/.julia/packages/MsgPack/pN9xd/src/unpack.jl:396
  [4] _unpack_array(io::IOBuffer, n::UInt8, #unused#::Type{ComplexF64}, strict::Tuple{})
    @ MsgPack ~/.julia/packages/MsgPack/pN9xd/src/unpack.jl:411
  [5] unpack_format(io::IOBuffer, f::MsgPack.ArrayFixFormat, #unused#::Type{ComplexF64}, strict::Tuple{})
    @ MsgPack ~/.julia/packages/MsgPack/pN9xd/src/unpack.jl:402
  [6] unpack_type(io::IOBuffer, byte::UInt8, t::MsgPack.ArrayType, ::Type{ComplexF64}; strict::Tuple{})
    @ MsgPack ~/.julia/packages/MsgPack/pN9xd/src/unpack.jl:390
  [7] unpack(io::IOBuffer, ::Type{ComplexF64}; strict::Tuple{})
    @ MsgPack ~/.julia/packages/MsgPack/pN9xd/src/unpack.jl:32
  [8] unpack(bytes::Vector{UInt8}, ::Type{ComplexF64}; strict::Tuple{})
    @ MsgPack ~/.julia/packages/MsgPack/pN9xd/src/unpack.jl:8
  [9] unpack(bytes::Vector{UInt8}, ::Type{ComplexF64})
    @ MsgPack ~/.julia/packages/MsgPack/pN9xd/src/unpack.jl:8
 [10] top-level scope
    @ REPL[46]:1

What am I doing wrong here?

synthfi avatar Sep 25 '22 02:09 synthfi