diff --git a/src/codec/decode.jl b/src/codec/decode.jl index 1648e52..3f32bb8 100644 --- a/src/codec/decode.jl +++ b/src/codec/decode.jl @@ -30,75 +30,65 @@ function decode(d::AbstractProtoDecoder, ::Type{T}) where {T <: Union{Enum{Int32 end decode(d::AbstractProtoDecoder, ::Type{T}) where {T <: Union{Float64,Float32}} = read(d.io, T) function decode!(d::AbstractProtoDecoder, buffer::Dict{K,V}) where {K,V<:_ScalarTypesEnum} - len = vbyte_decode(d.io, UInt32) - endpos = position(d.io) + len - while position(d.io) < endpos - field_number, wire_type = decode_tag(d) - key = decode(d, K) - field_number, wire_type = decode_tag(d) - val = decode(d, V) - buffer[key] = val - end - @assert position(d.io) == endpos + pair_len = vbyte_decode(d.io, UInt32) + pair_end_pos = position(d.io) + pair_len + field_number, wire_type = decode_tag(d) + key = decode(d, K) + field_number, wire_type = decode_tag(d) + val = decode(d, V) + @assert position(d.io) == pair_end_pos + buffer[key] = val nothing end function decode!(d::AbstractProtoDecoder, buffer::Dict{K,V}) where {K,V} - len = vbyte_decode(d.io, UInt32) - endpos = position(d.io) + len - while position(d.io) < endpos - field_number, wire_type = decode_tag(d) - key = decode(d, K) - field_number, wire_type = decode_tag(d) - val = decode(d, Ref{V}) - buffer[key] = val - end - @assert position(d.io) == endpos + pair_len = vbyte_decode(d.io, UInt32) + pair_end_pos = position(d.io) + pair_len + field_number, wire_type = decode_tag(d) + key = decode(d, K) + field_number, wire_type = decode_tag(d) + val = decode(d, Ref{V}) + @assert position(d.io) == pair_end_pos + buffer[key] = val nothing end for T in (:(:fixed), :(:zigzag)) @eval function decode!(d::AbstractProtoDecoder, buffer::Dict{K,V}, ::Type{Val{Tuple{Nothing,$(T)}}}) where {K,V} - len = vbyte_decode(d.io, UInt32) - endpos = position(d.io) + len - while position(d.io) < endpos - field_number, wire_type = decode_tag(d) - key = decode(d, K) - field_number, wire_type = decode_tag(d) - val = decode(d, V, Val{$(T)}) - buffer[key] = val - end - @assert position(d.io) == endpos + pair_len = vbyte_decode(d.io, UInt32) + pair_end_pos = position(d.io) + pair_len + field_number, wire_type = decode_tag(d) + key = decode(d, K) + field_number, wire_type = decode_tag(d) + val = decode(d, V, Val{$(T)}) + @assert position(d.io) == pair_end_pos + buffer[key] = val nothing end @eval function decode!(d::AbstractProtoDecoder, buffer::Dict{K,V}, ::Type{Val{Tuple{$(T),Nothing}}}) where {K,V} - len = vbyte_decode(d.io, UInt32) - endpos = position(d.io) + len - while position(d.io) < endpos - field_number, wire_type = decode_tag(d) - key = decode(d, K, Val{$(T)}) - field_number, wire_type = decode_tag(d) - val = decode(d, V) - buffer[key] = val - end - @assert position(d.io) == endpos + pair_len = vbyte_decode(d.io, UInt32) + pair_end_pos = position(d.io) + pair_len + field_number, wire_type = decode_tag(d) + key = decode(d, K, Val{$(T)}) + field_number, wire_type = decode_tag(d) + val = decode(d, V) + @assert position(d.io) == pair_end_pos + buffer[key] = val nothing end end for T in (:(:fixed), :(:zigzag)), S in (:(:fixed), :(:zigzag)) @eval function decode!(d::AbstractProtoDecoder, buffer::Dict{K,V}, ::Type{Val{Tuple{$(T),$(S)}}}) where {K,V} - len = vbyte_decode(d.io, UInt32) - endpos = position(d.io) + len - while position(d.io) < endpos - field_number, wire_type = decode_tag(d) - key = decode(d, K, Val{$(T)}) - field_number, wire_type = decode_tag(d) - val = decode(d, V, Val{$(S)}) - buffer[key] = val - end - @assert position(d.io) == endpos + pair_len = vbyte_decode(d.io, UInt32) + pair_end_pos = position(d.io) + pair_len + field_number, wire_type = decode_tag(d) + key = decode(d, K, Val{$(T)}) + field_number, wire_type = decode_tag(d) + val = decode(d, V, Val{$(S)}) + @assert position(d.io) == pair_end_pos + buffer[key] = val nothing end end diff --git a/src/codec/encode.jl b/src/codec/encode.jl index 38ae1cc..2505971 100644 --- a/src/codec/encode.jl +++ b/src/codec/encode.jl @@ -139,40 +139,52 @@ function _encode(io::IO, x::Vector{T}) where {T<:Union{UInt32,UInt64,Int32,Int64 return nothing end -function _encode(_e::ProtoEncoder, x::Dict{K,V}) where {K,V} - maybe_ensure_room(_e.io, 2length(x)) +function encode(e::ProtoEncoder, i::Int, x::Dict{K,V}) where {K,V} + maybe_ensure_room(e.io, 2*(length(x)+1)) for (k, v) in x - encode(_e, 1, k) - encode(_e, 2, v) + # encode header for key-value pair message + encode_tag(e, i, LENGTH_DELIMITED) + vbyte_encode(e.io, UInt32(_encoded_size(k, 1) + _encoded_size(v, 2))) + encode(e, 1, k) + encode(e, 2, v) end nothing end for T in (:(:fixed), :(:zigzag)) - @eval function _encode(_e::ProtoEncoder, x::Dict{K,V}, ::Type{Val{Tuple{$(T),Nothing}}}) where {K,V} - maybe_ensure_room(_e.io, 2length(x)) + @eval function encode(e::ProtoEncoder, i::Int, x::Dict{K,V}, ::Type{Val{Tuple{$(T),Nothing}}}) where {K,V} + maybe_ensure_room(e.io, 2*(length(x)+1)) for (k, v) in x - encode(_e, 1, k, Val{$(T)}) - encode(_e, 2, v) + # encode header for key-value pair message + encode_tag(e, i, LENGTH_DELIMITED) + vbyte_encode(e.io, UInt32(_encoded_size(k, 1, Val{$(T)}) + _encoded_size(v, 2))) + encode(e, 1, k, Val{$(T)}) + encode(e, 2, v) end nothing end - @eval function _encode(_e::ProtoEncoder, x::Dict{K,V}, ::Type{Val{Tuple{Nothing,$(T)}}}) where {K,V} - maybe_ensure_room(_e.io, 2length(x)) + @eval function encode(e::ProtoEncoder, i::Int, x::Dict{K,V}, ::Type{Val{Tuple{Nothing,$(T)}}}) where {K,V} + maybe_ensure_room(e.io, 2*(length(x)+1)) for (k, v) in x - encode(_e, 1, k) - encode(_e, 2, v, Val{$(T)}) + # encode header for key-value pair message + encode_tag(e, i, LENGTH_DELIMITED) + vbyte_encode(e.io, UInt32(_encoded_size(k, 1) + _encoded_size(v, 2, Val{$(T)}))) + encode(e, 1, k) + encode(e, 2, v, Val{$(T)}) end nothing end end for T in (:(:fixed), :(:zigzag)), S in (:(:fixed), :(:zigzag)) - @eval function _encode(_e::AbstractProtoEncoder, x::Dict{K,V}, ::Type{Val{Tuple{$(T),$(S)}}}) where {K,V} - maybe_ensure_room(_e.io, 2length(x)) + @eval function encode(e::AbstractProtoEncoder, i::Int, x::Dict{K,V}, ::Type{Val{Tuple{$(T),$(S)}}}) where {K,V} + maybe_ensure_room(e.io, 2*(length(x)+1)) for (k, v) in x - encode(_e, 1, k, Val{$(T)}) - encode(_e, 2, v, Val{$(S)}) + # encode header for key-value pair message + encode_tag(e, i, LENGTH_DELIMITED) + vbyte_encode(e.io, UInt32(_encoded_size(k, 1, Val{$(T)}) + _encoded_size(v, 2, Val{$(S)}))) + encode(e, 1, k, Val{$(T)}) + encode(e, 2, v, Val{$(S)}) end nothing end @@ -269,18 +281,6 @@ function encode(e::AbstractProtoEncoder, i::Int, x::Vector{T}) where {T<:Union{U return nothing end -function encode(e::AbstractProtoEncoder, i::Int, x::Dict{K,V}) where {K,V} - encode_tag(e, i, LENGTH_DELIMITED) - _with_size(_encode, e.io, e, x) - return nothing -end - -function encode(e::AbstractProtoEncoder, i::Int, x::Dict{K,V}, ::Type{W}) where {K,V,W} - encode_tag(e, i, LENGTH_DELIMITED) - _with_size(_encode, e.io, e, x, W) - return nothing -end - function encode(e::AbstractProtoEncoder, i::Int, x::Vector{T}, ::Type{Val{:zigzag}}) where {T<:Union{Int32,Int64}} encode_tag(e, i, LENGTH_DELIMITED) _with_size(_encode, e.io, e.io, x, Val{:zigzag}) diff --git a/src/codec/encoded_size.jl b/src/codec/encoded_size.jl index 758d737..a211896 100644 --- a/src/codec/encoded_size.jl +++ b/src/codec/encoded_size.jl @@ -19,7 +19,7 @@ _encoded_size(x::T, ::Type{Val{:fixed}}) where {T<:Union{Int32,UInt32,Int64,UInt # For Length-Delimited fields we don't include the encoded number of bytes # unless we also provide the field number in which case we encode both the -# tag and lenght +# tag and length _with_size(n::Int) = (n + _encoded_size(n)) _encoded_size(x::String) = sizeof(x) @@ -29,19 +29,41 @@ _encoded_size(xs::AbstractVector{T}) where {T<:Union{UInt8,Bool,Float64,Float32} _encoded_size(xs::AbstractVector{T}) where {T<:Union{String,AbstractVector{UInt8}}} = sum(x->_with_size(_encoded_size(x)), xs, init=0) _encoded_size(xs::AbstractVector{T}, ::Type{Val{:fixed}}) where {T<:Union{Int32,UInt32,Int64,UInt64}} = sizeof(xs) -# Dicts add dummy tags to both keys and values -_encoded_size(d::AbstractDict) = mapreduce(x->_encoded_size(x.first, 1) + _encoded_size(x.second, 2), +, d, init=0) +# Dicts add dummy tags to both keys and values and to each pair +# _encoded_size(::AbstractDict) does not include the "pair" tag and field number +# those are added in the _encoded_size(::AbstractDict, ::Int) methods below because the field number +# is not known at this point +function _encoded_size(d::AbstractDict) + mapreduce(x->begin + total_size = _encoded_size(x.first, 1) + _encoded_size(x.second, 2) + return _varint_size(total_size) + total_size + end, +, d, init=0) +end +_encoded_size(xs::AbstractDict, i::Int) = _encoded_size(i << 3) * length(xs) + _encoded_size(xs) for T in (:(:fixed), :(:zigzag)) - @eval _encoded_size(d::AbstractDict, ::Type{Val{Tuple{$(T),Nothing}}}) = mapreduce(x->_encoded_size(x.first, 1, Val{$(T)}) + _encoded_size(x.second, 2), +, d, init=0) - @eval _encoded_size(d::AbstractDict, ::Type{Val{Tuple{Nothing,$(T)}}}) = mapreduce(x->_encoded_size(x.first, 1) + _encoded_size(x.second, 2, Val{$(T)}), +, d, init=0) + @eval _encoded_size(d::AbstractDict, ::Type{Val{Tuple{$(T),Nothing}}}) = mapreduce(x->begin + total_size = _encoded_size(x.first, 1, Val{$(T)}) + _encoded_size(x.second, 2) + return _varint_size(total_size) + total_size + end, +, d, init=0) + @eval _encoded_size(xs::AbstractDict, i::Int, ::Type{Val{Tuple{$(T),Nothing}}}) = _encoded_size(i << 3) * length(xs) + _encoded_size(xs, Val{Tuple{$(T),Nothing}}) + + @eval _encoded_size(d::AbstractDict, ::Type{Val{Tuple{Nothing,$(T)}}}) = mapreduce(x->begin + total_size = _encoded_size(x.first, 1) + _encoded_size(x.second, 2, Val{$(T)}) + return _varint_size(total_size) + total_size + end, +, d, init=0) + @eval _encoded_size(xs::AbstractDict, i::Int, ::Type{Val{Tuple{Nothing,$(T)}}}) = _encoded_size(i << 3) * length(xs) + _encoded_size(xs, Val{Tuple{Nothing,$(T)}}) - @eval _encoded_size(xs::Union{AbstractDict,AbstractVector}, i::Int, ::Type{Val{$(T)}}) = _encoded_size(i << 3) + _with_size(_encoded_size(xs, Val{$(T)})) - @eval _encoded_size(xs::Union{Int32,Int64,UInt64,UInt32}, i::Int, ::Type{Val{$(T)}}) = _encoded_size(i << 3) + _encoded_size(xs, Val{$(T)}) + @eval _encoded_size(xs::AbstractVector, i::Int, ::Type{Val{$(T)}}) = _encoded_size(i << 3) + _with_size(_encoded_size(xs, Val{$(T)})) + @eval _encoded_size(xs::Union{Int32,Int64,UInt64,UInt32}, i::Int, ::Type{Val{$(T)}}) = _encoded_size(i << 3) + _encoded_size(xs, Val{$(T)}) end for T in (:(:fixed), :(:zigzag)), S in (:(:fixed), :(:zigzag)) - @eval _encoded_size(d::AbstractDict, ::Type{Val{Tuple{$(T),$(S)}}}) = mapreduce(x->_encoded_size(x.first, 1, Val{$(S)}) + _encoded_size(x.second, 2, Val{$(S)}), +, d, init=0) + @eval _encoded_size(d::AbstractDict, ::Type{Val{Tuple{$(T),$(S)}}}) = mapreduce(x->begin + total_size = _encoded_size(x.first, 1, Val{$(T)}) + _encoded_size(x.second, 2, Val{$(S)}) + return _varint_size(total_size) + total_size + end, +, d, init=0) + @eval _encoded_size(xs::AbstractDict, i::Int, ::Type{Val{Tuple{$(T),$(S)}}}) = _encoded_size(i << 3) * length(xs) + _encoded_size(xs, Val{Tuple{$(T),$(S)}}) end # These methods handle fields that refer to messages/groups diff --git a/test/test_decode.jl b/test/test_decode.jl index bbe9bf9..810ae74 100644 --- a/test/test_decode.jl +++ b/test/test_decode.jl @@ -69,7 +69,7 @@ wire_type(::Type{<:AbstractString}) = Codecs.LENGTH_ function test_decode(input_bytes, expected, V::Type=Nothing) w = wire_type(typeof(expected), V) input_bytes = collect(input_bytes) - if w == Codecs.LENGTH_DELIMITED + if w == Codecs.LENGTH_DELIMITED && !isa(expected, Dict) input_bytes = vcat(UInt8(length(input_bytes)), input_bytes) end @@ -89,7 +89,10 @@ function test_decode(input_bytes, expected, V::Type=Nothing) x = x[] elseif isa(expected, Dict) x = Dict{keytype(expected), valtype(expected)}() - decode!(e, x) + while !eof(e.io) + num, tag = PB.decode_tag(e) + decode!(e, x) + end else x = decode(e, typeof(expected)) end @@ -100,7 +103,10 @@ function test_decode(input_bytes, expected, V::Type=Nothing) x = x[] elseif isa(expected, Dict) x = Dict{keytype(expected), valtype(expected)}() - decode!(e, x, V) + while !eof(e.io) + num, tag = PB.decode_tag(e) + decode!(e, x, V) + end else x = decode(e, typeof(expected), V) end @@ -205,44 +211,47 @@ end end @testset "map" begin - @testset "string,string" begin test_decode([0x0a, 0x01, 0x62, 0x12, 0x01, 0x61], Dict{String,String}("b" => "a")) end + @testset "string,string" begin test_decode([0x0a, 0x06, 0x0a, 0x01, 0x62, 0x12, 0x01, 0x61], Dict{String,String}("b" => "a")) end + + @testset "multiple string,string" begin test_decode([0x0a, 0x06, 0x0a, 0x01, 0x63, 0x12, 0x01, 0x64, 0x0a, 0x06, 0x0a, 0x01, 0x62, 0x12, 0x01, 0x61], Dict{String,String}("b" => "a", "c" => "d")) end + @testset "multiple string,string reversed" begin test_decode([0x0a, 0x06, 0x0a, 0x01, 0x62, 0x12, 0x01, 0x61, 0x0a, 0x06, 0x0a, 0x01, 0x63, 0x12, 0x01, 0x64], Dict{String,String}("b" => "a", "c" => "d")) end - @testset "int32,string" begin test_decode([0x08, 0x01, 0x12, 0x01, 0x61], Dict{Int32,String}(1 => "a")) end - @testset "int64,string" begin test_decode([0x08, 0x01, 0x12, 0x01, 0x61], Dict{Int64,String}(1 => "a")) end - @testset "uint32,string" begin test_decode([0x08, 0x01, 0x12, 0x01, 0x61], Dict{UInt32,String}(1 => "a")) end - @testset "uint64,string" begin test_decode([0x08, 0x01, 0x12, 0x01, 0x61], Dict{UInt64,String}(1 => "a")) end - @testset "bool,string" begin test_decode([0x08, 0x01, 0x12, 0x01, 0x61], Dict{Bool,String}(true => "a")) end + @testset "int32,string" begin test_decode([0x0a, 0x05, 0x08, 0x01, 0x12, 0x01, 0x61], Dict{Int32,String}(1 => "a")) end + @testset "int64,string" begin test_decode([0x0a, 0x05, 0x08, 0x01, 0x12, 0x01, 0x61], Dict{Int64,String}(1 => "a")) end + @testset "uint32,string" begin test_decode([0x0a, 0x05, 0x08, 0x01, 0x12, 0x01, 0x61], Dict{UInt32,String}(1 => "a")) end + @testset "uint64,string" begin test_decode([0x0a, 0x05, 0x08, 0x01, 0x12, 0x01, 0x61], Dict{UInt64,String}(1 => "a")) end + @testset "bool,string" begin test_decode([0x0a, 0x05, 0x08, 0x01, 0x12, 0x01, 0x61], Dict{Bool,String}(true => "a")) end - @testset "sfixed32,string" begin test_decode([0x0d, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Dict{Int32,String}(1 => "a"), Val{Tuple{:fixed,Nothing}}) end - @testset "sfixed64,string" begin test_decode([0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Dict{Int64,String}(1 => "a"), Val{Tuple{:fixed,Nothing}}) end - @testset "fixed32,string" begin test_decode([0x0d, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Dict{UInt32,String}(1 => "a"), Val{Tuple{:fixed,Nothing}}) end - @testset "fixed64,string" begin test_decode([0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Dict{UInt64,String}(1 => "a"), Val{Tuple{:fixed,Nothing}}) end + @testset "sfixed32,string" begin test_decode([0x0a, 0x08, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Dict{Int32,String}(1 => "a"), Val{Tuple{:fixed,Nothing}}) end + @testset "sfixed64,string" begin test_decode([0x0a, 0x0c, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Dict{Int64,String}(1 => "a"), Val{Tuple{:fixed,Nothing}}) end + @testset "fixed32,string" begin test_decode([0x0a, 0x08, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Dict{UInt32,String}(1 => "a"), Val{Tuple{:fixed,Nothing}}) end + @testset "fixed64,string" begin test_decode([0x0a, 0x0c, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Dict{UInt64,String}(1 => "a"), Val{Tuple{:fixed,Nothing}}) end - @testset "sint32,string" begin test_decode([0x08, 0x02, 0x12, 0x01, 0x61], Dict{Int32,String}(1 => "a"), Val{Tuple{:zigzag,Nothing}}) end - @testset "sint64,string" begin test_decode([0x08, 0x02, 0x12, 0x01, 0x61], Dict{Int64,String}(1 => "a"), Val{Tuple{:zigzag,Nothing}}) end + @testset "sint32,string" begin test_decode([0x0a, 0x05, 0x08, 0x02, 0x12, 0x01, 0x61], Dict{Int32,String}(1 => "a"), Val{Tuple{:zigzag,Nothing}}) end + @testset "sint64,string" begin test_decode([0x0a, 0x05, 0x08, 0x02, 0x12, 0x01, 0x61], Dict{Int64,String}(1 => "a"), Val{Tuple{:zigzag,Nothing}}) end - @testset "string,int32" begin test_decode([0x0a, 0x01, 0x61, 0x10, 0x01], Dict{String,Int32}("a" => 1)) end - @testset "string,int64" begin test_decode([0x0a, 0x01, 0x61, 0x10, 0x01], Dict{String,Int64}("a" => 1)) end - @testset "string,uint32" begin test_decode([0x0a, 0x01, 0x61, 0x10, 0x01], Dict{String,UInt32}("a" => 1)) end - @testset "string,uint64" begin test_decode([0x0a, 0x01, 0x61, 0x10, 0x01], Dict{String,UInt64}("a" => 1)) end - @testset "string,bool" begin test_decode([0x0a, 0x01, 0x61, 0x10, 0x01], Dict{String,Bool}("a" => true)) end + @testset "string,int32" begin test_decode([0x0a, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x01], Dict{String,Int32}("a" => 1)) end + @testset "string,int64" begin test_decode([0x0a, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x01], Dict{String,Int64}("a" => 1)) end + @testset "string,uint32" begin test_decode([0x0a, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x01], Dict{String,UInt32}("a" => 1)) end + @testset "string,uint64" begin test_decode([0x0a, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x01], Dict{String,UInt64}("a" => 1)) end + @testset "string,bool" begin test_decode([0x0a, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x01], Dict{String,Bool}("a" => true)) end - @testset "string,sfixed32" begin test_decode([0x0a, 0x01, 0x61, 0x15, 0x01, 0x00, 0x00, 0x00], Dict{String,Int32}("a" => 1), Val{Tuple{Nothing,:fixed}}) end - @testset "string,sfixed64" begin test_decode([0x0a, 0x01, 0x61, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Dict{String,Int64}("a" => 1), Val{Tuple{Nothing,:fixed}}) end - @testset "string,fixed32" begin test_decode([0x0a, 0x01, 0x61, 0x15, 0x01, 0x00, 0x00, 0x00], Dict{String,UInt32}("a" => 1), Val{Tuple{Nothing,:fixed}}) end - @testset "string,fixed64" begin test_decode([0x0a, 0x01, 0x61, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Dict{String,UInt64}("a" => 1), Val{Tuple{Nothing,:fixed}}) end + @testset "string,sfixed32" begin test_decode([0x0a, 0x08, 0x0a, 0x01, 0x61, 0x15, 0x01, 0x00, 0x00, 0x00], Dict{String,Int32}("a" => 1), Val{Tuple{Nothing,:fixed}}) end + @testset "string,sfixed64" begin test_decode([0x0a, 0x0c, 0x0a, 0x01, 0x61, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Dict{String,Int64}("a" => 1), Val{Tuple{Nothing,:fixed}}) end + @testset "string,fixed32" begin test_decode([0x0a, 0x08, 0x0a, 0x01, 0x61, 0x15, 0x01, 0x00, 0x00, 0x00], Dict{String,UInt32}("a" => 1), Val{Tuple{Nothing,:fixed}}) end + @testset "string,fixed64" begin test_decode([0x0a, 0x0c, 0x0a, 0x01, 0x61, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Dict{String,UInt64}("a" => 1), Val{Tuple{Nothing,:fixed}}) end - @testset "string,sint32" begin test_decode([0x0a, 0x01, 0x61, 0x10, 0x02], Dict{String,Int32}("a" => 1), Val{Tuple{Nothing,:zigzag}}) end - @testset "string,sint64" begin test_decode([0x0a, 0x01, 0x61, 0x10, 0x02], Dict{String,Int64}("a" => 1), Val{Tuple{Nothing,:zigzag}}) end + @testset "string,sint32" begin test_decode([0x0a, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x02], Dict{String,Int32}("a" => 1), Val{Tuple{Nothing,:zigzag}}) end + @testset "string,sint64" begin test_decode([0x0a, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x02], Dict{String,Int64}("a" => 1), Val{Tuple{Nothing,:zigzag}}) end - @testset "sfixed32,sfixed32" begin test_decode([0x0d, 0x01, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00], Dict{Int32,Int32}(1 => 1), Val{Tuple{:fixed,:fixed}}) end - @testset "sfixed64,sfixed64" begin test_decode([0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Dict{Int64,Int64}(1 => 1), Val{Tuple{:fixed,:fixed}}) end - @testset "fixed32,fixed32" begin test_decode([0x0d, 0x01, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00], Dict{UInt32,UInt32}(1 => 1), Val{Tuple{:fixed,:fixed}}) end - @testset "fixed64,fixed64" begin test_decode([0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Dict{UInt64,UInt64}(1 => 1), Val{Tuple{:fixed,:fixed}}) end + @testset "sfixed32,sfixed32" begin test_decode([0x0a, 0x0a, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00], Dict{Int32,Int32}(1 => 1), Val{Tuple{:fixed,:fixed}}) end + @testset "sfixed64,sfixed64" begin test_decode([0x0a, 0x12, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Dict{Int64,Int64}(1 => 1), Val{Tuple{:fixed,:fixed}}) end + @testset "fixed32,fixed32" begin test_decode([0x0a, 0x0a, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00], Dict{UInt32,UInt32}(1 => 1), Val{Tuple{:fixed,:fixed}}) end + @testset "fixed64,fixed64" begin test_decode([0x0a, 0x12, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Dict{UInt64,UInt64}(1 => 1), Val{Tuple{:fixed,:fixed}}) end - @testset "sint32,sint32" begin test_decode([0x08, 0x02, 0x10, 0x02], Dict{Int32,Int32}(1 => 1), Val{Tuple{:zigzag,:zigzag}}) end - @testset "sint64,sint64" begin test_decode([0x08, 0x02, 0x10, 0x02], Dict{Int64,Int64}(1 => 1), Val{Tuple{:zigzag,:zigzag}}) end + @testset "sint32,sint32" begin test_decode([0x0a, 0x04, 0x08, 0x02, 0x10, 0x02], Dict{Int32,Int32}(1 => 1), Val{Tuple{:zigzag,:zigzag}}) end + @testset "sint64,sint64" begin test_decode([0x0a, 0x04, 0x08, 0x02, 0x10, 0x02], Dict{Int64,Int64}(1 => 1), Val{Tuple{:zigzag,:zigzag}}) end end @testset "message" begin diff --git a/test/test_encode.jl b/test/test_encode.jl index b63c54f..939395d 100644 --- a/test/test_encode.jl +++ b/test/test_encode.jl @@ -80,7 +80,7 @@ function test_encode(input, i, w::WireType, expected, V::Type=Nothing) encode(d, i, input, V) end bytes = take!(d.io) - if isa(input, AbstractVector) && eltype(input) <: Union{Vector{UInt8}, String, TestInner} + if (isa(input, AbstractVector) && eltype(input) <: Union{Vector{UInt8}, String, TestInner}) || isa(input, AbstractDict) j = 1 while !isempty(bytes) tag = bytes[1] @@ -207,37 +207,38 @@ end end @testset "map" begin - @testset "string,string" begin test_encode(Dict{String,String}("b" => "a"), 2, Codecs.LENGTH_DELIMITED, [0x0a, 0x01, 0x62, 0x12, 0x01, 0x61]) end + @testset "string,string" begin test_encode(Dict{String,String}("b" => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x06, 0x0a, 0x01, 0x62, 0x12, 0x01, 0x61]) end + @testset "multiple string,string" begin test_encode(Dict{String,String}("b" => "a", "c" => "d"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x06, 0x0a, 0x01, 0x63, 0x12, 0x01, 0x64, 0x12, 0x06, 0x0a, 0x01, 0x62, 0x12, 0x01, 0x61]) end - @testset "int32,string" begin test_encode(Dict{Int32,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x08, 0x01, 0x12, 0x01, 0x61]) end - @testset "int64,string" begin test_encode(Dict{Int64,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x08, 0x01, 0x12, 0x01, 0x61]) end - @testset "uint32,string" begin test_encode(Dict{UInt32,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x08, 0x01, 0x12, 0x01, 0x61]) end - @testset "uint64,string" begin test_encode(Dict{UInt64,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x08, 0x01, 0x12, 0x01, 0x61]) end - @testset "bool,string" begin test_encode(Dict{Bool,String}(true => "a"), 2, Codecs.LENGTH_DELIMITED, [0x08, 0x01, 0x12, 0x01, 0x61]) end + @testset "int32,string" begin test_encode(Dict{Int32,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x08, 0x01, 0x12, 0x01, 0x61]) end + @testset "int64,string" begin test_encode(Dict{Int64,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x08, 0x01, 0x12, 0x01, 0x61]) end + @testset "uint32,string" begin test_encode(Dict{UInt32,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x08, 0x01, 0x12, 0x01, 0x61]) end + @testset "uint64,string" begin test_encode(Dict{UInt64,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x08, 0x01, 0x12, 0x01, 0x61]) end + @testset "bool,string" begin test_encode(Dict{Bool,String}(true => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x08, 0x01, 0x12, 0x01, 0x61]) end - @testset "sfixed32,string" begin test_encode(Dict{Int32,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x0d, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Val{Tuple{:fixed,Nothing}}) end - @testset "sfixed64,string" begin test_encode(Dict{Int64,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Val{Tuple{:fixed,Nothing}}) end - @testset "fixed32,string" begin test_encode(Dict{UInt32,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x0d, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Val{Tuple{:fixed,Nothing}}) end - @testset "fixed64,string" begin test_encode(Dict{UInt64,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Val{Tuple{:fixed,Nothing}}) end + @testset "sfixed32,string" begin test_encode(Dict{Int32,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x08, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Val{Tuple{:fixed,Nothing}}) end + @testset "sfixed64,string" begin test_encode(Dict{Int64,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x0c, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Val{Tuple{:fixed,Nothing}}) end + @testset "fixed32,string" begin test_encode(Dict{UInt32,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x08, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Val{Tuple{:fixed,Nothing}}) end + @testset "fixed64,string" begin test_encode(Dict{UInt64,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x0c, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x61], Val{Tuple{:fixed,Nothing}}) end - @testset "sint32,string" begin test_encode(Dict{Int32,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x08, 0x02, 0x12, 0x01, 0x61], Val{Tuple{:zigzag,Nothing}}) end - @testset "sint64,string" begin test_encode(Dict{Int64,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x08, 0x02, 0x12, 0x01, 0x61], Val{Tuple{:zigzag,Nothing}}) end + @testset "sint32,string" begin test_encode(Dict{Int32,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x08, 0x02, 0x12, 0x01, 0x61], Val{Tuple{:zigzag,Nothing}}) end + @testset "sint64,string" begin test_encode(Dict{Int64,String}(1 => "a"), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x08, 0x02, 0x12, 0x01, 0x61], Val{Tuple{:zigzag,Nothing}}) end - @testset "string,int32" begin test_encode(Dict{String,Int32}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x0a, 0x01, 0x61, 0x10, 0x01]) end - @testset "string,int64" begin test_encode(Dict{String,Int64}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x0a, 0x01, 0x61, 0x10, 0x01]) end - @testset "string,uint32" begin test_encode(Dict{String,UInt32}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x0a, 0x01, 0x61, 0x10, 0x01]) end - @testset "string,uint64" begin test_encode(Dict{String,UInt64}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x0a, 0x01, 0x61, 0x10, 0x01]) end - @testset "string,bool" begin test_encode(Dict{String,Bool}("a" => true), 2, Codecs.LENGTH_DELIMITED, [0x0a, 0x01, 0x61, 0x10, 0x01]) end + @testset "string,int32" begin test_encode(Dict{String,Int32}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x01]) end + @testset "string,int64" begin test_encode(Dict{String,Int64}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x01]) end + @testset "string,uint32" begin test_encode(Dict{String,UInt32}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x01]) end + @testset "string,uint64" begin test_encode(Dict{String,UInt64}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x01]) end + @testset "string,bool" begin test_encode(Dict{String,Bool}("a" => true), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x05, 0x0a, 0x01, 0x61, 0x10, 0x01]) end - @testset "string,sfixed32" begin test_encode(Dict{String,Int32}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x0a, 0x01, 0x61, 0x15, 0x01, 0x00, 0x00, 0x00], Val{Tuple{Nothing,:fixed}}) end - @testset "string,sfixed64" begin test_encode(Dict{String,Int64}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x0a, 0x01, 0x61, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Val{Tuple{Nothing,:fixed}}) end - @testset "string,fixed32" begin test_encode(Dict{String,UInt32}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x0a, 0x01, 0x61, 0x15, 0x01, 0x00, 0x00, 0x00], Val{Tuple{Nothing,:fixed}}) end - @testset "string,fixed64" begin test_encode(Dict{String,UInt64}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x0a, 0x01, 0x61, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Val{Tuple{Nothing,:fixed}}) end + @testset "string,sfixed32" begin test_encode(Dict{String,Int32}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x08, 0x0a, 0x01, 0x61, 0x15, 0x01, 0x00, 0x00, 0x00], Val{Tuple{Nothing,:fixed}}) end + @testset "string,sfixed64" begin test_encode(Dict{String,Int64}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x0c, 0x0a, 0x01, 0x61, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Val{Tuple{Nothing,:fixed}}) end + @testset "string,fixed32" begin test_encode(Dict{String,UInt32}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x08, 0x0a, 0x01, 0x61, 0x15, 0x01, 0x00, 0x00, 0x00], Val{Tuple{Nothing,:fixed}}) end + @testset "string,fixed64" begin test_encode(Dict{String,UInt64}("a" => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x0c, 0x0a, 0x01, 0x61, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Val{Tuple{Nothing,:fixed}}) end - @testset "sfixed32,sfixed32" begin test_encode(Dict{Int32,Int32}(1 => 1), 2, Codecs.LENGTH_DELIMITED, [0x0d, 0x01, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00], Val{Tuple{:fixed,:fixed}}) end - @testset "sfixed64,sfixed64" begin test_encode(Dict{Int64,Int64}(1 => 1), 2, Codecs.LENGTH_DELIMITED, [0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Val{Tuple{:fixed,:fixed}}) end - @testset "fixed32,fixed32" begin test_encode(Dict{UInt32,UInt32}(1 => 1), 2, Codecs.LENGTH_DELIMITED, [0x0d, 0x01, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00], Val{Tuple{:fixed,:fixed}}) end - @testset "fixed64,fixed64" begin test_encode(Dict{UInt64,UInt64}(1 => 1), 2, Codecs.LENGTH_DELIMITED, [0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Val{Tuple{:fixed,:fixed}}) end + @testset "sfixed32,sfixed32" begin test_encode(Dict{Int32,Int32}(1 => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x0a, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00], Val{Tuple{:fixed,:fixed}}) end + @testset "sfixed64,sfixed64" begin test_encode(Dict{Int64,Int64}(1 => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x12, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Val{Tuple{:fixed,:fixed}}) end + @testset "fixed32,fixed32" begin test_encode(Dict{UInt32,UInt32}(1 => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x0a, 0x0d, 0x01, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x00], Val{Tuple{:fixed,:fixed}}) end + @testset "fixed64,fixed64" begin test_encode(Dict{UInt64,UInt64}(1 => 1), 2, Codecs.LENGTH_DELIMITED, [0x12, 0x12, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], Val{Tuple{:fixed,:fixed}}) end end @testset "message" begin @@ -402,51 +403,107 @@ end # S T D T L T D E @test _encoded_size([NonEmptyMessage(typemax(UInt32), NonEmptyMessage(typemax(UInt32), nothing))], Val{:group}) == 1 + (1 + 5) + (1 + (1 + (1 + 5))) + 1 # T L D T L D - @test _encoded_size(Dict("K" => UInt8[0xff])) == ((1 + 1 + 1) + (1 + 1 + 1)) - @test _encoded_size(Dict("K" => "S")) == ((1 + 1 + 1) + (1 + 1 + 1)) - @test _encoded_size(Dict("KEY" => "STR")) == ((1 + 1 + 3) + (1 + 1 + 3)) + @test _encoded_size(Dict("K" => UInt8[0xff])) == ((1 + 1 + 1) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict("K" => UInt8[0xff]), 1) == ((1 + 1 + 1) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict("K" => "S")) == ((1 + 1 + 1) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict("K" => "S"), 1) == ((1 + 1 + 1) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict("KEY" => "STR")) == ((1 + 1 + 3) + (1 + 1 + 3)) + 1 + @test _encoded_size(Dict("KEY" => "STR"), 1) == ((1 + 1 + 3) + (1 + 1 + 3)) + 2 + @test _encoded_size(Dict("KEY1" => "STR1", "KEY2" => "STR2")) == 2 * (((1 + 1 + 4) + (1 + 1 + 4)) + 1) + @test _encoded_size(Dict("KEY1" => "STR1", "KEY2" => "STR2"), 1) == 2 * (((1 + 1 + 4) + (1 + 1 + 4)) + 2) + @test _encoded_size(Dict("KEY1" => "STR1", "KEY2" => "STR2"), 128) == 2 * (((1 + 1 + 4) + (1 + 1 + 4)) + 3) # T L D T D - @test _encoded_size(Dict("K" => typemax(UInt32))) == ((1 + 1 + 1) + (1 + 5)) - @test _encoded_size(Dict("K" => typemax(UInt64))) == ((1 + 1 + 1) + (1 + 10)) - @test _encoded_size(Dict("K" => typemax(Int32))) == ((1 + 1 + 1) + (1 + 5)) - @test _encoded_size(Dict("K" => typemax(Int64))) == ((1 + 1 + 1) + (1 + 9)) - @test _encoded_size(Dict("K" => true)) == ((1 + 1 + 1) + (1 + 1)) - @test _encoded_size(Dict("K" => typemax(Int32)), Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 5)) - @test _encoded_size(Dict("K" => typemax(Int64)), Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 10)) - @test _encoded_size(Dict("K" => typemin(Int32)), Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 5)) - @test _encoded_size(Dict("K" => typemin(Int64)), Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 10)) - @test _encoded_size(Dict("K" => TestEnum.OTHER)) == ((1 + 1 + 1) + (1 + 1)) - - @test _encoded_size(Dict("K" => typemax(UInt32)), Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 4)) - @test _encoded_size(Dict("K" => typemax(UInt64)), Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 8)) - @test _encoded_size(Dict("K" => typemax(Int32)), Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 4)) - @test _encoded_size(Dict("K" => typemax(Int64)), Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 8)) - - @test _encoded_size(Dict("K" => EmptyMessage())) == ((1 + 1 + 1) + (1 + 1 + 0)) - # T L D T L T D T L T D - @test _encoded_size(Dict("K" => NonEmptyMessage(typemax(UInt32), NonEmptyMessage(typemax(UInt32), nothing)))) == ((1 + 1 + 1) + (1 + 1 + (1 + 5) + (1 + (1 + (1 + 5))))) - # T D T L D - @test _encoded_size(Dict(typemax(UInt32) => "V")) == ((1 + 5) + (1 + 1 + 1)) - @test _encoded_size(Dict(typemax(UInt64) => "V")) == ((1 + 10) + (1 + 1 + 1)) - @test _encoded_size(Dict(typemax(Int32) => "V")) == ((1 + 5) + (1 + 1 + 1)) - @test _encoded_size(Dict(typemax(Int64) => "V")) == ((1 + 9) + (1 + 1 + 1)) - @test _encoded_size(Dict(true => "V")) == ((1 + 1) + (1 + 1 + 1)) - @test _encoded_size(Dict(typemax(Int32) => "V"), Val{Tuple{:zigzag,Nothing}}) == ((1 + 5) + (1 + 1 + 1)) - @test _encoded_size(Dict(typemax(Int64) => "V"), Val{Tuple{:zigzag,Nothing}}) == ((1 + 10) + (1 + 1 + 1)) - @test _encoded_size(Dict(typemin(Int32) => "V"), Val{Tuple{:zigzag,Nothing}}) == ((1 + 5) + (1 + 1 + 1)) - @test _encoded_size(Dict(typemin(Int64) => "V"), Val{Tuple{:zigzag,Nothing}}) == ((1 + 10) + (1 + 1 + 1)) - @test _encoded_size(Dict(TestEnum.OTHER => "V")) == ((1 + 1) + (1 + 1 + 1)) - - @test _encoded_size(Dict(typemax(UInt32) => "V"), Val{Tuple{:fixed,Nothing}}) == ((1 + 4) + (1 + 1 + 1)) - @test _encoded_size(Dict(typemax(UInt64) => "V"), Val{Tuple{:fixed,Nothing}}) == ((1 + 8) + (1 + 1 + 1)) - @test _encoded_size(Dict(typemax(Int32) => "V"), Val{Tuple{:fixed,Nothing}}) == ((1 + 4) + (1 + 1 + 1)) - @test _encoded_size(Dict(typemax(Int64) => "V"), Val{Tuple{:fixed,Nothing}}) == ((1 + 8) + (1 + 1 + 1)) + @test _encoded_size(Dict("K" => typemax(UInt32))) == ((1 + 1 + 1) + (1 + 5)) + 1 + @test _encoded_size(Dict("K" => typemax(UInt32)), 1) == ((1 + 1 + 1) + (1 + 5)) + 2 + @test _encoded_size(Dict("K" => typemax(UInt64))) == ((1 + 1 + 1) + (1 + 10)) + 1 + @test _encoded_size(Dict("K" => typemax(UInt64)), 1) == ((1 + 1 + 1) + (1 + 10)) + 2 + @test _encoded_size(Dict("K" => typemax(Int32))) == ((1 + 1 + 1) + (1 + 5)) + 1 + @test _encoded_size(Dict("K" => typemax(Int32)), 1) == ((1 + 1 + 1) + (1 + 5)) + 2 + @test _encoded_size(Dict("K" => typemax(Int64))) == ((1 + 1 + 1) + (1 + 9)) + 1 + @test _encoded_size(Dict("K" => typemax(Int64)), 1) == ((1 + 1 + 1) + (1 + 9)) + 2 + @test _encoded_size(Dict("K" => true)) == ((1 + 1 + 1) + (1 + 1)) + 1 + @test _encoded_size(Dict("K" => true), 1) == ((1 + 1 + 1) + (1 + 1)) + 2 + @test _encoded_size(Dict("K" => typemax(Int32)), Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 5)) + 1 + @test _encoded_size(Dict("K" => typemax(Int32)), 1, Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 5)) + 2 + @test _encoded_size(Dict("K" => typemax(Int64)), Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 10)) + 1 + @test _encoded_size(Dict("K" => typemax(Int64)), 1, Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 10)) + 2 + @test _encoded_size(Dict("K" => typemin(Int32)), Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 5)) + 1 + @test _encoded_size(Dict("K" => typemin(Int32)), 1, Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 5)) + 2 + @test _encoded_size(Dict("K" => typemin(Int64)), Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 10)) + 1 + @test _encoded_size(Dict("K" => typemin(Int64)), 1, Val{Tuple{Nothing,:zigzag}}) == ((1 + 1 + 1) + (1 + 10)) + 2 + @test _encoded_size(Dict("K" => TestEnum.OTHER)) == ((1 + 1 + 1) + (1 + 1)) + 1 + @test _encoded_size(Dict("K" => TestEnum.OTHER), 1) == ((1 + 1 + 1) + (1 + 1)) + 2 + + @test _encoded_size(Dict("K" => typemax(UInt32)), Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 4)) + 1 + @test _encoded_size(Dict("K" => typemax(UInt32)), 1, Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 4)) + 2 + @test _encoded_size(Dict("K" => typemax(UInt64)), Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 8)) + 1 + @test _encoded_size(Dict("K" => typemax(UInt64)), 1, Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 8)) + 2 + @test _encoded_size(Dict("K" => typemax(Int32)), Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 4)) + 1 + @test _encoded_size(Dict("K" => typemax(Int32)), 1, Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 4)) + 2 + @test _encoded_size(Dict("K" => typemax(Int64)), Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 8)) + 1 + @test _encoded_size(Dict("K" => typemax(Int64)), 1, Val{Tuple{Nothing,:fixed}}) == ((1 + 1 + 1) + (1 + 8)) + 2 + + @test _encoded_size(Dict("K" => EmptyMessage())) == ((1 + 1 + 1) + (1 + 1 + 0)) + 1 + @test _encoded_size(Dict("K" => EmptyMessage()), 1) == ((1 + 1 + 1) + (1 + 1 + 0)) + 2 + # T L D T L T D T L T D + @test _encoded_size(Dict("K" => NonEmptyMessage(typemax(UInt32), NonEmptyMessage(typemax(UInt32), nothing)))) == ((1 + 1 + 1) + (1 + 1 + (1 + 5) + (1 + (1 + (1 + 5))))) + 1 + @test _encoded_size(Dict("K" => NonEmptyMessage(typemax(UInt32), NonEmptyMessage(typemax(UInt32), nothing))), 1) == ((1 + 1 + 1) + (1 + 1 + (1 + 5) + (1 + (1 + (1 + 5))))) + 2 + # T D T L D TH + @test _encoded_size(Dict(typemax(UInt32) => "V")) == ((1 + 5) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemax(UInt32) => "V"), 1) == ((1 + 5) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(typemax(UInt64) => "V")) == ((1 + 10) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemax(UInt64) => "V"), 1) == ((1 + 10) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(typemax(Int32) => "V")) == ((1 + 5) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemax(Int32) => "V"), 1) == ((1 + 5) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(typemax(Int64) => "V")) == ((1 + 9) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemax(Int64) => "V"), 1) == ((1 + 9) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(true => "V")) == ((1 + 1) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(true => "V"), 1) == ((1 + 1) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(typemax(Int32) => "V"), Val{Tuple{:zigzag,Nothing}}) == ((1 + 5) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemax(Int32) => "V"), 1, Val{Tuple{:zigzag,Nothing}}) == ((1 + 5) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(typemax(Int64) => "V"), Val{Tuple{:zigzag,Nothing}}) == ((1 + 10) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemax(Int64) => "V"), 1, Val{Tuple{:zigzag,Nothing}}) == ((1 + 10) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(typemin(Int32) => "V"), Val{Tuple{:zigzag,Nothing}}) == ((1 + 5) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemin(Int32) => "V"), 1, Val{Tuple{:zigzag,Nothing}}) == ((1 + 5) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(typemin(Int64) => "V"), Val{Tuple{:zigzag,Nothing}}) == ((1 + 10) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemin(Int64) => "V"), 1, Val{Tuple{:zigzag,Nothing}}) == ((1 + 10) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(TestEnum.OTHER => "V")) == ((1 + 1) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(TestEnum.OTHER => "V"), 1) == ((1 + 1) + (1 + 1 + 1)) + 2 + + @test _encoded_size(Dict(typemax(UInt32) => "V"), Val{Tuple{:fixed,Nothing}}) == ((1 + 4) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemax(UInt32) => "V"), 1, Val{Tuple{:fixed,Nothing}}) == ((1 + 4) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(typemax(UInt64) => "V"), Val{Tuple{:fixed,Nothing}}) == ((1 + 8) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemax(UInt64) => "V"), 1, Val{Tuple{:fixed,Nothing}}) == ((1 + 8) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(typemax(Int32) => "V"), Val{Tuple{:fixed,Nothing}}) == ((1 + 4) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemax(Int32) => "V"), 1, Val{Tuple{:fixed,Nothing}}) == ((1 + 4) + (1 + 1 + 1)) + 2 + @test _encoded_size(Dict(typemax(Int64) => "V"), Val{Tuple{:fixed,Nothing}}) == ((1 + 8) + (1 + 1 + 1)) + 1 + @test _encoded_size(Dict(typemax(Int64) => "V"), 1, Val{Tuple{:fixed,Nothing}}) == ((1 + 8) + (1 + 1 + 1)) + 2 + + @test _encoded_size(Dict(typemax(UInt32) => typemax(UInt32)), Val{Tuple{:fixed,:fixed}}) == ((1 + 4) + (1 + 4)) + 1 + @test _encoded_size(Dict(typemax(UInt32) => typemax(UInt32)), 1, Val{Tuple{:fixed,:fixed}}) == ((1 + 4) + (1 + 4)) + 2 + @test _encoded_size(Dict(typemax(UInt64) => typemax(UInt64)), Val{Tuple{:fixed,:fixed}}) == ((1 + 8) + (1 + 8)) + 1 + @test _encoded_size(Dict(typemax(UInt64) => typemax(UInt64)), 1, Val{Tuple{:fixed,:fixed}}) == ((1 + 8) + (1 + 8)) + 2 + @test _encoded_size(Dict(typemax(Int32) => typemax(Int32)), Val{Tuple{:fixed,:fixed}}) == ((1 + 4) + (1 + 4)) + 1 + @test _encoded_size(Dict(typemax(Int32) => typemax(Int32)), 1, Val{Tuple{:fixed,:fixed}}) == ((1 + 4) + (1 + 4)) + 2 + @test _encoded_size(Dict(typemax(Int64) => typemax(Int64)), Val{Tuple{:fixed,:fixed}}) == ((1 + 8) + (1 + 8)) + 1 + @test _encoded_size(Dict(typemax(Int64) => typemax(Int64)), 1, Val{Tuple{:fixed,:fixed}}) == ((1 + 8) + (1 + 8)) + 2 + + @test _encoded_size(Dict(typemax(Int32) => typemax(Int32)), Val{Tuple{:zigzag,:zigzag}}) == ((1 + 5) + (1 + 5)) + 1 + @test _encoded_size(Dict(typemax(Int32) => typemax(Int32)), 1, Val{Tuple{:zigzag,:zigzag}}) == ((1 + 5) + (1 + 5)) + 2 + @test _encoded_size(Dict(typemax(Int64) => typemax(Int64)), Val{Tuple{:zigzag,:zigzag}}) == ((1 + 10) + (1 + 10)) + 1 + @test _encoded_size(Dict(typemax(Int64) => typemax(Int64)), 1, Val{Tuple{:zigzag,:zigzag}}) == ((1 + 10) + (1 + 10)) + 2 + @test _encoded_size(Dict(typemin(Int32) => typemax(Int32)), Val{Tuple{:zigzag,:zigzag}}) == ((1 + 5) + (1 + 5)) + 1 + @test _encoded_size(Dict(typemin(Int32) => typemax(Int32)), 1, Val{Tuple{:zigzag,:zigzag}}) == ((1 + 5) + (1 + 5)) + 2 + @test _encoded_size(Dict(typemin(Int64) => typemax(Int64)), Val{Tuple{:zigzag,:zigzag}}) == ((1 + 10) + (1 + 10)) + 1 + @test _encoded_size(Dict(typemin(Int64) => typemax(Int64)), 1, Val{Tuple{:zigzag,:zigzag}}) == ((1 + 10) + (1 + 10)) + 2 @test _encoded_size(typemax(Float32)) == 4 @test _encoded_size(typemax(Float64)) == 8 @test _encoded_size([typemax(Float32)]) == 4 @test _encoded_size([typemax(Float64)]) == 8 - @test _encoded_size(Dict("K" => typemax(Float32))) == ((1 + 1 + 1) + (1 + 4)) - @test _encoded_size(Dict("K" => typemax(Float64))) == ((1 + 1 + 1) + (1 + 8)) + @test _encoded_size(Dict("K" => typemax(Float32))) == ((1 + 1 + 1) + (1 + 4)) + 1 + @test _encoded_size(Dict("K" => typemax(Float32)), 1) == ((1 + 1 + 1) + (1 + 4)) + 2 + @test _encoded_size(Dict("K" => typemax(Float64))) == ((1 + 1 + 1) + (1 + 8)) + 1 + @test _encoded_size(Dict("K" => typemax(Float64)), 1) == ((1 + 1 + 1) + (1 + 8)) + 2 end end # module \ No newline at end of file diff --git a/test/test_protojl.jl b/test/test_protojl.jl index 25eeb04..7f273dc 100644 --- a/test/test_protojl.jl +++ b/test/test_protojl.jl @@ -230,4 +230,51 @@ end test_by_field(x, DuplicatedMessage(DuplicatedInnerMessage(UInt32(43), UInt32[1, 2, 3, 4], DuplicatedMessage(DuplicatedInnerMessage(UInt32(43), UInt32[1, 2, 5, 6], nothing))))) end end +end + +module TestMappingStruct +using Test +using ProtoBuf + +@testset "Roundtrip a dictionary mapping" begin + tmpdir = mktempdir() + protojl("pair_struct.proto", joinpath(pkgdir(ProtoBuf), "test", "test_protos"), tmpdir, always_use_modules=false, parametrize_oneofs=true); + include(joinpath(tmpdir, "pair_struct_pb.jl")) + + function encode_bytes(msg) + io = IOBuffer() + e = PB.ProtoEncoder(io) + PB.encode(e, msg) + return take!(io) + end + + function decode_bytes(::Type{T}, bytes) where {T} + io = IOBuffer(bytes) + d = PB.ProtoDecoder(io) + return PB.decode(d, T) + end + + test_dictionary = Dict{String, Int64}( + "field1"=>1, + "field2"=>-5, + "field3"=>120, + ) + + dict_message = Map(test_dictionary) + pairs_message = Pairs([ProtoPair(k, v) for (k, v) in test_dictionary]) + + encoded_dict = encode_bytes(dict_message) + encoded_pairs = encode_bytes(pairs_message) + + decoded_dict = decode_bytes(Map, encoded_pairs) + decoded_pairs = decode_bytes(Pairs, encoded_dict) + + @test encoded_dict == encoded_pairs + + @test typeof(dict_message) == typeof(decoded_dict) + @test dict_message.map_field == decoded_dict.map_field + + @test typeof(pairs_message) == typeof(decoded_pairs) + @test pairs_message.map_field == decoded_pairs.map_field +end end \ No newline at end of file diff --git a/test/test_protos/pair_struct.proto b/test/test_protos/pair_struct.proto new file mode 100644 index 0000000..7ba99f9 --- /dev/null +++ b/test/test_protos/pair_struct.proto @@ -0,0 +1,15 @@ +syntax = "proto2"; + + +message ProtoPair { + optional string key = 1; + optional int64 value = 2; +} + +message Pairs { + repeated ProtoPair map_field = 7; +} + +message Map { + map map_field = 7; +} \ No newline at end of file