jli  Linuxx86_641.10.3v1.10.30b4590a5507d3f3046e5bafc007cacbbfc9b310bu MsgPackS"NqK#r-8 60/opt/julia/packages/MsgPack/LleAi/src/MsgPack.jlOVAk1 [)*Serialization./opt/julia/packages/MsgPack/LleAi/src/types.jlOVA0/opt/julia/packages/MsgPack/LleAi/src/formats.jlOVA./opt/julia/packages/MsgPack/LleAi/src/views.jlOVA//opt/julia/packages/MsgPack/LleAi/src/unpack.jlOVA-/opt/julia/packages/MsgPack/LleAi/src/pack.jlOVA CoremуJ5Basemу]J5MainmуJ5ArgToolsBń x(mуF K5 Artifactsmr-V3|mу K5Base64UlD*_mу> K5CRC32c\y.jmуj K5 FileWatchingXzsy`{,zmуh& K5LibdluVW59˗,mу-" K5LoggingT{VhUXM=mуrU" K5MmapP~:xg,Omу|' K5NetworkOptionsC0YW,mуʠ, K5SHAQ<$!<%mу1 K5 Serialization [)*k1mу-G K5Sockets1V$ bdސݗmуYBY K5UnicodeP>I>Nrmуeszo K5 LinearAlgebraSm7̏mуuux K5 OpenBLAS_jll[(Śb6EcQ FmуDux K5libblastrampoline_jllLSۆ }lxӠmу^} K5MarkdownZPn7z`smу/Ed~ K5Printfg^cX׸QDmу;h K5Random_ɢ?\Ymу? K5TarOi>աmу!t, K5DatesEY8pj2 mуX K5FuturebS;3{I xVMmуsD K5InteractiveUtilsWL ~@'ZmуVg K5LibGit2Z[&RPTv3EКRmу8J K5 LibGit2_jll YXg}]$mуD K5 MbedTLS_jllAX 3ȡ_mу- K5 LibSSH2_jlloTZk)߆ Julia type interface. The subtypes of `AbstractMsgPackType` are: - [`IntegerType`](@ref) - [`NilType`](@ref) - [`BooleanType`](@ref) - [`FloatType`](@ref) - [`StringType`](@ref) - [`BinaryType`](@ref) - [`ArrayType`](@ref) - [`MapType`](@ref) - [`ExtensionType`](@ref) - [`AnyType`](@ref) - [`StructType`](@ref) """ abstract type AbstractMsgPackType end """ IntegerType <: AbstractMsgPackType A Julia type corresponding to the MessagePack Integer type. If `msgpack_type(T)` is defined to return `IntegerType()`, then `T` must support: - `to_msgpack(::IntegerType, ::T)::S` - `from_msgpack(::Type{T}, ::S)::T` - standard numeric comparators (`>`, `<`, `==`, etc.) against values of type `S` where `S` may be one of the following types: - `UInt8` - `UInt16` - `UInt32` - `UInt64` - `Int8` - `Int16` - `Int32` - `Int64` """ struct IntegerType <: AbstractMsgPackType end """ NilType <: AbstractMsgPackType A Julia type corresponding to the MessagePack Nil type. If `msgpack_type(T)` is defined to return `NilType()`, then `T` must support: - `from_msgpack(::Type{T}, ::Nothing)::T` """ struct NilType <: AbstractMsgPackType end """ BooleanType <: AbstractMsgPackType A Julia type corresponding to the MessagePack Boolean type. If `msgpack_type(T)` is defined to return `BooleanType()`, then `T` must support: - `to_msgpack(::BooleanType, ::T)::Bool` - `from_msgpack(::Type{T}, ::Bool)::T` """ struct BooleanType <: AbstractMsgPackType end """ FloatType <: AbstractMsgPackType A Julia type corresponding to the MessagePack Float type. If `msgpack_type(T)` is defined to return `FloatType()`, then `T` must support: - `to_msgpack(::FloatType, ::T)::S` - `from_msgpack(::Type{T}, ::S)::T` - standard numeric comparators (`>`, `<`, `==`, etc.) against values of type `S` where `S` may be one of the following types: - `Float32` - `Float64` """ struct FloatType <: AbstractMsgPackType end """ StringType <: AbstractMsgPackType A Julia type corresponding to the MessagePack String type. If `msgpack_type(T)` is defined to return `StringType()`, then `T` must support: - `to_msgpack(::StringType, ::T)::String` - `from_msgpack(::Type{T}, ::String)::T` """ struct StringType <: AbstractMsgPackType end """ BinaryType <: AbstractMsgPackType A Julia type corresponding to the MessagePack Binary type. If `msgpack_type(T)` is defined to return `BinaryType()`, then `T` must support: - `to_msgpack(::BinaryType, ::T)::Vector{UInt8}` - `from_msgpack(::Type{T}, ::Vector{UInt8})::T` """ struct BinaryType <: AbstractMsgPackType end """ ArrayType <: AbstractMsgPackType A Julia type corresponding to the MessagePack Array type. If `msgpack_type(T)` is defined to return `ArrayType()`, then `T` must support: - `length` - `iterate` - `MsgPack._eltype(T)` (falls back to `eltype(T)`) and/or must support: - `to_msgpack(::ArrayType, ::T)::AbstractArray` - `from_msgpack(::Type{T}, ::Vector)::T` """ struct ArrayType <: AbstractMsgPackType end """ MapType <: AbstractMsgPackType A Julia type corresponding to the MessagePack Map type. If `msgpack_type(T)` is defined to return `MapType()`, then `T` must support: - `length` - `iterate` - `MsgPack._keytype(T)` (falls back to `keytype(T)`) - `MsgPack._valtype(T)` (falls back to `valtype(T)`) and/or must support: - `to_msgpack(::ArrayType, ::T)::AbstractDict` - `from_msgpack(::Type{T}, ::Dict)::T` """ struct MapType <: AbstractMsgPackType end """ ExtensionType <: AbstractMsgPackType A Julia type corresponding to the MessagePack Extension type. If `msgpack_type(T)` is defined to return `ExtensionType()`, then `T` must support: - `to_msgpack(::ExtensionType, ::T)::Extension` - `from_msgpack(::Type{T}, ::Extension)::T` See also: [`Extension`](@ref) """ struct ExtensionType <: AbstractMsgPackType end """ AnyType <: AbstractMsgPackType The fallback return type of `msgpack_type(::Type)`, indicating that the given Julia type does not have a known corresponding MessagePack type. """ struct AnyType <: AbstractMsgPackType end """ StructType <: AbstractMsgPackType If `msgpack_type(T)` is defined to return `StructType`, `T` will be (de)serialized as a MessagePack Map type, where each key-value pair corresponds to a field of `T`. - `T` must be an instantiable Julia type that supports `fieldcount`, `fieldtype`, `fieldname`, and `getfield`. - `T` must support a valid [`construct`](@ref) definition (supported by default if `T` supports e.g. `T((getfield(::T, i) for i in 1:fieldcount(T))...)`) - [`pack`](@ref) will always serialize `T`'s fields in the order specified by `fieldname`. In other words, it is generally guaranteed that bytes written by `pack(x::T)` can be unpacked via `unpack(bytes, T; strict=(T,))`. """ struct StructType <: AbstractMsgPackType end @deprecate MutableStructType() StructType() false @deprecate ImmutableStructType() StructType() false ##### ##### `msgpack_type`, `to_msgpack`, `from_msgpack` defaults ##### """ msgpack_type(::Type{T}) where {T} Return an instance of the [`AbstractMsgPackType`](@ref) subtype corresponding to `T`'s intended MessagePack representation. For example: ``` msgpack_type(::Type{UUID}) = StringType() ``` If this method is overloaded such that `msgpack_type(T) === M()`, then `to_msgpack(::M, ::T)` and `from_msgpack(::Type{T}, x)` should also be overloaded to handle conversion of `T` instances to/from MsgPack-compatible types. By default, this method returns `AnyType()`. While this fallback method need not be overloaded to support deserialization of `T` instances via `unpack`, `msgpack_type(T)` must be overloaded to return a non-`AnyType` `AbstractMsgPackType` instance in order to support serializing `T` instances via `pack`. See also: [`from_msgpack`](@ref), [`to_msgpack`](@ref) """ msgpack_type(::Type) = AnyType() """ to_msgpack(::M, value_to_serialize::T) where {M<:AbstractMsgPackType,T} Return an "`M`-compatible" representation of `value_to_serialize` (for compatibility definitions, see the docstrings for subtypes of [`AbstractMsgPackType`](@ref)). By default, `to_msgpack` simply returns `value_to_serialize` directly. The implementation of [`pack`](@ref) utilizes this function for every value encountered during serialization, calling it in a manner similar to the following psuedocode: ``` t = msgpack_type(T) value_in_compatible_representation = to_msgpack(t, value_to_serialize::T) _serialize_in_msgpack_format(t, value_in_compatible_representation) ``` For example, if `msgpack_type(UUID)` was defined to return `StringType()`, an appropriate `to_msgpack` implementation might be: ``` to_msgpack(::StringType, uuid::UUID) = string(uuid) ``` See also: [`from_msgpack`](@ref), [`msgpack_type`](@ref), [`AbstractMsgPackType`](@ref) """ to_msgpack(::AbstractMsgPackType, x) = x """ from_msgpack(::Type{T}, value_deserialized_by_msgpack) where {T} Return the `value_deserialized_by_msgpack` converted to type `T`. By default, this method simply calls `convert(T, value_deserialized_by_msgpack)`. The implementation of [`unpack`](@ref) calls this function on every deserialized value; in this case, `T` is generally derived from the type specified by the caller of `unpack`. For example, if `msgpack_type(UUID)` was defined to return `StringType()`, an appropriate `from_msgpack` implementation might be: ``` from_msgpack(::Type{UUID}, uuid::AbstractString) = UUID(uuid) ``` See also: [`to_msgpack`](@ref), [`msgpack_type`](@ref), [`AbstractMsgPackType`](@ref) """ from_msgpack(T::Type, x) = convert(T, x) # int-y things msgpack_type(::Type{<:Integer}) = IntegerType() # nil-y things msgpack_type(::Type{Nothing}) = NilType() msgpack_type(::Type{Missing}) = NilType() from_msgpack(::Type{Missing}, ::Nothing) = missing # bool-y things msgpack_type(::Type{Bool}) = BooleanType() # float-y things msgpack_type(::Type{<:AbstractFloat}) = FloatType() # string-y things msgpack_type(::Type{<:AbstractString}) = StringType() msgpack_type(::Type{Symbol}) = StringType() msgpack_type(::Type{Char}) = StringType() to_msgpack(::StringType, x::Char) = string(x) to_msgpack(::StringType, x::Symbol) = _symbol_to_string(x) from_msgpack(::Type{Char}, x::AbstractString) = first(x) from_msgpack(::Type{Symbol}, x::AbstractString) = Symbol(x) # array-y things msgpack_type(::Type{<:AbstractArray}) = ArrayType() msgpack_type(::Type{<:AbstractSet}) = ArrayType() msgpack_type(::Type{<:Tuple}) = ArrayType() from_msgpack(::Type{T}, x::Vector) where {T<:AbstractSet} = convert(T, Set(x)) from_msgpack(::Type{T}, x::Vector) where {T<:Tuple} = convert(T, (x...,)) # map-y things msgpack_type(::Type{<:AbstractDict}) = MapType() msgpack_type(::Type{<:NamedTuple}) = MapType() @generated function to_msgpack(::MapType, x::NamedTuple) fields = Any[] for i in 1:fieldcount(x) push!(fields, Expr(:tuple, Expr(:quote, fieldname(x, i)), :(getfield(x, $i)))) end return Expr(:tuple, fields...) end @generated function from_msgpack(::Type{T}, x::Dict) where {T<:NamedTuple} fields = Any[] for i in 1:fieldcount(T) name = fieldname(T, i) strname = string(name) push!(fields, :($name = x[$strname])) end return Expr(:tuple, fields...) end ##### ##### `Extension` ##### """ struct Extension type::Int8 data::Vector{UInt8} end A wrapper for bytes formatted to the MessagePack Extension type specification. See also: [`extserialize`](@ref), [`extdeserialize`](@ref) """ struct Extension type::Int8 data::Vector{UInt8} end Base.:(==)(a::Extension, b::Extension) = a.type == b.type && a.data == b.data msgpack_type(::Type{Extension}) = ExtensionType() @deprecate Ext(type, data) MsgPack.Extension(type, data) """ extserialize(type, x) Return `Extension(type, data)` where `data` is the result of calling Julia's built-in `serialize` function on `x`, facilitating direct serialization Julia values to MessagePack format: ``` julia> struct Point{T} x::T y::T end julia> val = [Point(rand(), rand()) for _ in 1:100]; julia> bytes = MsgPack.pack(MsgPack.extserialize(123, x)); julia> type, new_val = MsgPack.extdeserialize(MsgPack.unpack(bytes)); julia> type == 123 true julia> new_val == val true ``` Note that `extserialize`/[`extdeserialize`](@ref) are subject to the same caveat as Julia's built-in `serialize`/`deserialize` functions: "In general, this process will not work if the reading and writing are done by different versions of Julia, or an instance of Julia with a different system image.". See also: [`Extension`](@ref), [`extdeserialize`](@ref) """ function extserialize(type, x) io = IOBuffer() serialize(io, x) return Extension(type, take!(io)) end """ extdeserialize(x::Extension) Return `(x.type, value)` where `value` is the result of calling Julia's built-in `deserialize` function on `x.data`. This function is meant to be used in conjuction with [`extserialize`](@ref); see that function's docstring for more details. See also: [`Extension`](@ref), [`extserialize`](@ref) """ extdeserialize(x::Extension) = (x.type, deserialize(IOBuffer(x.data))) ##### ##### `Skip` ##### struct Skip{T} end msgpack_type(::Type{Skip{T}}) where {T} = msgpack_type(T) from_msgpack(::Type{T}, x) where {T<:Skip} = T() ##### ##### `PointerString` ##### struct PointerString ptr::Ptr{UInt8} len::UInt64 end Base.sizeof(s::PointerString) = s.len Base.write(io::IO, s::PointerString) = Base.unsafe_write(io, s.ptr, s.len) from_msgpack(::Type{Symbol}, x::PointerString) = ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int), x.ptr, x.len) from_msgpack(::Type{PointerString}, x::PointerString) = x from_msgpack(S::Type, x::PointerString) = from_msgpack(S, unsafe_string(x.ptr, x.len)) _symbol_to_string(x::Symbol) = PointerString(Base.unsafe_convert(Ptr{UInt8}, x), sizeof(x)) 0/opt/julia/packages/MsgPack/LleAi/src/formats.jl"abstract type AbstractMsgPackFormat end ##### ##### `int` family ##### # `fixint` struct IntFixPositiveFormat <: AbstractMsgPackFormat byte::UInt8 end struct IntFixNegativeFormat <: AbstractMsgPackFormat byte::Int8 end Base.@pure magic_byte_min(::Type{IntFixPositiveFormat}) = 0x00 Base.@pure magic_byte_max(::Type{IntFixPositiveFormat}) = 0x7f Base.@pure magic_byte_min(::Type{IntFixNegativeFormat}) = 0xe0 Base.@pure magic_byte_max(::Type{IntFixNegativeFormat}) = 0xff # `uint` struct UInt8Format <: AbstractMsgPackFormat end struct UInt16Format <: AbstractMsgPackFormat end struct UInt32Format <: AbstractMsgPackFormat end struct UInt64Format <: AbstractMsgPackFormat end Base.@pure magic_byte(::Type{UInt8Format}) = 0xcc Base.@pure magic_byte(::Type{UInt16Format}) = 0xcd Base.@pure magic_byte(::Type{UInt32Format}) = 0xce Base.@pure magic_byte(::Type{UInt64Format}) = 0xcf # `int` struct Int8Format <: AbstractMsgPackFormat end struct Int16Format <: AbstractMsgPackFormat end struct Int32Format <: AbstractMsgPackFormat end struct Int64Format <: AbstractMsgPackFormat end Base.@pure magic_byte(::Type{Int64Format}) = 0xd3 Base.@pure magic_byte(::Type{Int32Format}) = 0xd2 Base.@pure magic_byte(::Type{Int16Format}) = 0xd1 Base.@pure magic_byte(::Type{Int8Format}) = 0xd0 ##### ##### `nil` family ##### struct NilFormat <: AbstractMsgPackFormat end Base.@pure magic_byte(::Type{NilFormat}) = 0xc0 ##### ##### `bool` family ##### struct FalseFormat <: AbstractMsgPackFormat end struct TrueFormat <: AbstractMsgPackFormat end Base.@pure magic_byte(::Type{FalseFormat}) = 0xc2 Base.@pure magic_byte(::Type{TrueFormat}) = 0xc3 ##### ##### `float` family ##### struct Float32Format <: AbstractMsgPackFormat end struct Float64Format <: AbstractMsgPackFormat end Base.@pure magic_byte(::Type{Float32Format}) = 0xca Base.@pure magic_byte(::Type{Float64Format}) = 0xcb ##### ##### `str` family ##### struct StrFixFormat <: AbstractMsgPackFormat byte::UInt8 end struct Str8Format <: AbstractMsgPackFormat end struct Str16Format <: AbstractMsgPackFormat end struct Str32Format <: AbstractMsgPackFormat end Base.@pure magic_byte_min(::Type{StrFixFormat}) = 0xa0 Base.@pure magic_byte_max(::Type{StrFixFormat}) = 0xbf Base.@pure magic_byte(::Type{Str8Format}) = 0xd9 Base.@pure magic_byte(::Type{Str16Format}) = 0xda Base.@pure magic_byte(::Type{Str32Format}) = 0xdb ##### ##### `bin` family ##### struct Bin8Format <: AbstractMsgPackFormat end struct Bin16Format <: AbstractMsgPackFormat end struct Bin32Format <: AbstractMsgPackFormat end Base.@pure magic_byte(::Type{Bin8Format}) = 0xc4 Base.@pure magic_byte(::Type{Bin16Format}) = 0xc5 Base.@pure magic_byte(::Type{Bin32Format}) = 0xc6 ##### ##### `array` family ##### struct ArrayFixFormat <: AbstractMsgPackFormat byte::UInt8 end struct Array16Format <: AbstractMsgPackFormat end struct Array32Format <: AbstractMsgPackFormat end Base.@pure magic_byte_min(::Type{ArrayFixFormat}) = 0x90 Base.@pure magic_byte_max(::Type{ArrayFixFormat}) = 0x9f Base.@pure magic_byte(::Type{Array16Format}) = 0xdc Base.@pure magic_byte(::Type{Array32Format}) = 0xdd ##### ##### `map` family ##### struct MapFixFormat <: AbstractMsgPackFormat byte::UInt8 end struct Map16Format <: AbstractMsgPackFormat end struct Map32Format <: AbstractMsgPackFormat end Base.@pure magic_byte_min(::Type{MapFixFormat}) = 0x80 Base.@pure magic_byte_max(::Type{MapFixFormat}) = 0x8f Base.@pure magic_byte(::Type{Map16Format}) = 0xde Base.@pure magic_byte(::Type{Map32Format}) = 0xdf ##### ##### `ext` family ##### struct ExtFix1Format <: AbstractMsgPackFormat end struct ExtFix2Format <: AbstractMsgPackFormat end struct ExtFix4Format <: AbstractMsgPackFormat end struct ExtFix8Format <: AbstractMsgPackFormat end struct ExtFix16Format <: AbstractMsgPackFormat end struct Ext8Format <: AbstractMsgPackFormat end struct Ext16Format <: AbstractMsgPackFormat end struct Ext32Format <: AbstractMsgPackFormat end Base.@pure magic_byte(::Type{ExtFix1Format}) = 0xd4 Base.@pure magic_byte(::Type{ExtFix2Format}) = 0xd5 Base.@pure magic_byte(::Type{ExtFix4Format}) = 0xd6 Base.@pure magic_byte(::Type{ExtFix8Format}) = 0xd7 Base.@pure magic_byte(::Type{ExtFix16Format}) = 0xd8 Base.@pure magic_byte(::Type{Ext8Format}) = 0xc7 Base.@pure magic_byte(::Type{Ext16Format}) = 0xc8 Base.@pure magic_byte(::Type{Ext32Format}) = 0xc9 ./opt/julia/packages/MsgPack/LleAi/src/views.jl ##### ##### `ArrayView` ##### """ ArrayView{T} <: AbstractVector{T} A Julia struct that wraps a MessagePack byte buffer to provide an immutable view of the MessagePack Array stored within the wrapped byte buffer. This type is intended to be utilized via [`unpack`](@ref). For example, a call to `arr = unpack(bytes, ArrayView{Dict{String,Int32}})` will generally return a value more quickly than `arr = unpack(bytes, Vector{Dict{String,Int32}})`; the latter will perform full deserialization immediately while the former will only scan over `bytes` to tag the positions of `arr`'s elements, deferring the actual deserialization of these elements to the time of their access via `arr[index]`. Note that `ArrayView` does not implement any form of caching - repeat accesses of the same element will re-deserialize the element upon every access. """ struct ArrayView{T,B<:AbstractVector{UInt8},S<:Tuple} <: AbstractVector{T} bytes::B positions::Vector{UInt64} strict::S ArrayView{T}(bytes::B, positions, strict::S=()) where {T,B,S} = new{T,B,S}(bytes, positions, strict) end Base.IndexStyle(::Type{<:ArrayView}) = Base.IndexLinear() Base.size(arr::ArrayView) = (length(arr.positions),) Base.@propagate_inbounds function Base.getindex(arr::ArrayView{T}, i::Int) where {T} @boundscheck checkbounds(arr, i) @inbounds start = arr.positions[i] @inbounds stop = i == length(arr) ? length(arr.bytes) : arr.positions[i + 1] @inbounds current_bytes = view(arr.bytes, start:stop) return unpack(current_bytes, T; strict=arr.strict) end ##### ##### `MapView` ##### """ MapView{K,V} <: AbstractDict{K,V} Similar to [`ArrayView`](@ref), but provides an immutable view to a MessagePack Map rather than a MessagePack Array. This type is intended to be utilized via [`unpack`](@ref) in the same manner as `ArrayView`, and is similarly implements a "delay-deserialization-until-access" mechanism. """ struct MapView{K,V,B<:AbstractVector{UInt8},S<:Tuple} <: AbstractDict{K,V} bytes::B positions::Dict{K,UnitRange{UInt64}} strict::S MapView{K,V}(bytes::B, positions, strict::S=()) where {K,V,B,S} = new{K,V,B,S}(bytes, positions, strict) end Base.length(m::MapView) = length(m.positions) function _get_by_position(m::MapView{K,V}, position) where {K,V} return unpack(view(m.bytes, position), V; strict=m.strict) end Base.get(m::MapView, key) = _get_by_position(m, m.positions[key]) Base.haskey(m::MapView, key) = haskey(m.positions, key) function Base.get(m::MapView, key, default) haskey(m, key) && return get(m, key) return default end function Base.get(default::Base.Callable, m::MapView, key) haskey(m, key) && return get(m, key) return default() end function Base.iterate(m::MapView, prev...) x = iterate(m.positions, prev...) x isa Nothing && return nothing (key, position), state = x return key => _get_by_position(m, position), state end Base.keys(m::MapView) = keys(m.positions) Base.values(m::MapView) = (_get_by_position(m, i) for i in values(m.positions)) //opt/julia/packages/MsgPack/LleAi/src/unpack.jl\unpack(x; strict::Tuple=()) = unpack(x, Any; strict=strict) """ unpack(bytes, T::Type = Any; strict::Tuple=()) Return `unpack(IOBuffer(bytes), T; strict=strict)`. """ unpack(bytes, ::Type{T}; strict::Tuple=()) where {T} = unpack(IOBuffer(bytes), T; strict=strict) """ unpack(msgpack_byte_stream::IO, T::Type = Any; strict::Tuple=()) Return the Julia value of type `T` deserialized from `msgpack_byte_stream`. `T` is assumed to have valid [`msgpack_type`](@ref) and [`from_msgpack`](@ref) definitions. If `msgpack_type(T) === AnyType()`, `unpack` will deserialize the next MessagePack object from `msgpack_byte_stream` into the default Julia representation corresponding to the object's MessagePack type. For details on default Julia representations, see [`AbstractMsgPackType`](@ref). The `strict` keyword argument is a `Tuple` of `DataType`s where each element `S` must obey `msgpack_type(S) === StructType()`. `unpack` will assume that encountered MessagePack Maps to be deserialized to e.g. `S` will always contain fields that correspond strictly to the fields of `S`. In other words, the `i`th key in the Map must correspond to `fieldname(S, i)`, and the `i`th value must correspond to `getfield(::S, i)`. See also: [`pack`](@ref), [`construct`](@ref) """ unpack(io::IO, ::Type{T}; strict::Tuple=()) where {T} = unpack_type(io, read(io, UInt8), msgpack_type(T), T; strict=strict) ##### ##### `AnyType` ##### function unpack_type(io, byte, t::AnyType, U::Union; strict) A, B = U.a, U.b # Unions are sorted, so `Nothing`/`Missing` would be first if A === Nothing || A === Missing byte === magic_byte(NilFormat) && return from_msgpack(A, nothing) return unpack_type(io, byte, msgpack_type(B), B; strict=strict) end return _unpack_any(io, byte, U; strict=strict) end @inline unpack_type(io, byte, ::AnyType, T::Type; strict) = _unpack_any(io, byte, T; strict=strict) function _unpack_any(io, byte, ::Type{T}; strict) where {T} if byte <= magic_byte_max(IntFixPositiveFormat) return unpack_format(io, IntFixPositiveFormat(byte), T) elseif byte <= magic_byte_max(MapFixFormat) return unpack_format(io, MapFixFormat(byte), T, strict) elseif byte <= magic_byte_max(ArrayFixFormat) return unpack_format(io, ArrayFixFormat(byte), T, strict) elseif byte <= magic_byte_max(StrFixFormat) return unpack_format(io, StrFixFormat(byte), T) elseif byte === magic_byte(UInt8Format) return unpack_format(io, UInt8Format(), T) elseif byte === magic_byte(UInt16Format) return unpack_format(io, UInt16Format(), T) elseif byte === magic_byte(UInt32Format) return unpack_format(io, UInt32Format(), T) elseif byte === magic_byte(UInt64Format) return unpack_format(io, UInt64Format(), T) elseif byte === magic_byte(Int8Format) return unpack_format(io, Int8Format(), T) elseif byte === magic_byte(Int16Format) return unpack_format(io, Int16Format(), T) elseif byte === magic_byte(Int32Format) return unpack_format(io, Int32Format(), T) elseif byte === magic_byte(Int64Format) return unpack_format(io, Int64Format(), T) elseif byte === magic_byte(Float32Format) return unpack_format(io, Float32Format(), T) elseif byte === magic_byte(Float64Format) return unpack_format(io, Float64Format(), T) elseif byte === magic_byte(Str8Format) return unpack_format(io, Str8Format(), T) elseif byte === magic_byte(Str16Format) return unpack_format(io, Str16Format(), T) elseif byte === magic_byte(Str32Format) return unpack_format(io, Str32Format(), T) elseif byte === magic_byte(TrueFormat) return unpack_format(io, TrueFormat(), T) elseif byte === magic_byte(FalseFormat) return unpack_format(io, FalseFormat(), T) elseif byte === magic_byte(NilFormat) return unpack_format(io, NilFormat(), T) elseif byte === magic_byte(Array16Format) return unpack_format(io, Array16Format(), T, strict) elseif byte === magic_byte(Array32Format) return unpack_format(io, Array32Format(), T, strict) elseif byte === magic_byte(Map16Format) return unpack_format(io, Map16Format(), T, strict) elseif byte === magic_byte(Map32Format) return unpack_format(io, Map32Format(), T, strict) elseif byte === magic_byte(Ext8Format) return unpack_format(io, Ext8Format(), T) elseif byte === magic_byte(Ext16Format) return unpack_format(io, Ext16Format(), T) elseif byte === magic_byte(Ext32Format) return unpack_format(io, Ext32Format(), T) elseif byte === magic_byte(ExtFix1Format) return unpack_format(io, ExtFix1Format(), T) elseif byte === magic_byte(ExtFix2Format) return unpack_format(io, ExtFix2Format(), T) elseif byte === magic_byte(ExtFix4Format) return unpack_format(io, ExtFix4Format(), T) elseif byte === magic_byte(ExtFix8Format) return unpack_format(io, ExtFix8Format(), T) elseif byte === magic_byte(ExtFix16Format) return unpack_format(io, ExtFix16Format(), T) elseif byte === magic_byte(Bin8Format) return unpack_format(io, Bin8Format(), T) elseif byte === magic_byte(Bin16Format) return unpack_format(io, Bin16Format(), T) elseif byte === magic_byte(Bin32Format) return unpack_format(io, Bin32Format(), T) elseif byte >= magic_byte_min(IntFixNegativeFormat) return unpack_format(io, IntFixNegativeFormat(reinterpret(Int8, byte)), T) end invalid_unpack(io, byte, AnyType(), T) # should be unreachable, but ensures error is thrown if reached end ##### ##### `StructType` ##### struct FieldNotFound end """ construct(T::Type, args...) Return an instance of `T` given `args`; defaults to `T(args...)`. This function is meant to be overloaded for types `T` where `msgpack_type(T) === StructType()`. This function is called by [`unpack`](@ref) when deserializing `T` objects. When called for this purpose, `args` are field values for the given `T` instance and are passed in the order specified by `fieldname(T, i)`. If a given field of `T` wasn't found in the object's MessagePack Map representation, the corresponding value in `args` will be `MsgPack.FieldNotFound()`. """ construct(::Type{T}, args...) where {T} = T(args...) function unpack_type(io, byte, t::StructType, ::Type{T}; strict) where {T} if any(T <: S for S in strict) if byte > magic_byte_max(MapFixFormat) if byte === magic_byte(Map16Format) read(io, UInt16) elseif byte === magic_byte(Map32Format) read(io, UInt32) end end N = fieldcount(T) constructor = (args...) -> construct(T, args...) Base.@nexprs 32 i -> begin F_i = fieldtype(T, i) unpack_type(io, read(io, UInt8), StringType(), Skip{Symbol}; strict=strict) x_i = unpack_type(io, read(io, UInt8), msgpack_type(F_i), F_i; strict=strict) N == i && return Base.@ncall i constructor x end others = Any[] for i in 33:N F_i = fieldtype(T, i) unpack_type(io, read(io, UInt8), StringType(), Skip{Symbol}; strict=strict) push!(others, unpack_type(io, read(io, UInt8), msgpack_type(F_i), F_i; strict=strict)) end return constructor(x_1, x_2, x_3, x_4, x_5, x_6, x_7, x_8, x_9, x_10, x_11, x_12, x_13, x_14, x_15, x_16, x_17, x_18, x_19, x_20, x_21, x_22, x_23, x_24, x_25, x_26, x_27, x_28, x_29, x_30, x_31, x_32, others...) else if byte <= magic_byte_max(MapFixFormat) pair_count = xor(byte, magic_byte_min(MapFixFormat)) elseif byte === magic_byte(Map16Format) pair_count = ntoh(read(io, UInt16)) elseif byte === magic_byte(Map32Format) pair_count = ntoh(read(io, UInt32)) else invalid_unpack(io, byte, t, T) end N = fieldcount(T) fields = Any[FieldNotFound() for _ in 1:N] for _ in 1:pair_count key = unpack(io, Symbol) # TODO validation check? Base.@nif(33, # `i` in range 1:(33-1) i -> i <= N && fieldname(T, i) === key, i -> setindex!(fields, unpack(io, fieldtype(T, i); strict=strict), i), i -> begin is_field_still_unread = true for j in 33:N fieldname(T, j) === key || continue setindex!(fields, unpack(io, fieldtype(T, j); strict=strict), j) is_field_still_unread = false break end is_field_still_unread && unpack(io) end) end return construct(T, fields...) end end function unpack_type(io, byte, ::StructType, ::Type{Skip{T}}; strict) where {T} if any(T <: S for S in strict) N = fieldcount(T) byte > magic_byte_max(MapFixFormat) && read(io, UInt8) Base.@nexprs 32 i -> begin F_i = fieldtype(T, i) unpack_type(io, read(io, UInt8), StringType(), Skip{Symbol}; strict=strict) unpack_type(io, read(io, UInt8), msgpack_type(F_i), Skip{F_i}; strict=strict) N == i && return Skip{T}() end for i in 33:N F_i = fieldtype(T, i) unpack_type(io, read(io, UInt8), msgpack_type(F_i), Skip{F_i}; strict=strict) end else unpack_type(io, byte, MapType(), Skip{Dict{Symbol,Any}}; strict=strict) end return Skip{T}() end ##### ##### `IntegerType` ##### function unpack_type(io, byte, t::IntegerType, ::Type{T}; strict) where {T} if byte <= magic_byte_max(IntFixPositiveFormat) return unpack_format(io, IntFixPositiveFormat(byte), T) elseif byte === magic_byte(UInt8Format) return unpack_format(io, UInt8Format(), T) elseif byte === magic_byte(UInt16Format) return unpack_format(io, UInt16Format(), T) elseif byte === magic_byte(UInt32Format) return unpack_format(io, UInt32Format(), T) elseif byte === magic_byte(UInt64Format) return unpack_format(io, UInt64Format(), T) elseif byte === magic_byte(Int8Format) return unpack_format(io, Int8Format(), T) elseif byte === magic_byte(Int16Format) return unpack_format(io, Int16Format(), T) elseif byte === magic_byte(Int32Format) return unpack_format(io, Int32Format(), T) elseif byte === magic_byte(Int64Format) return unpack_format(io, Int64Format(), T) elseif byte >= magic_byte_min(IntFixNegativeFormat) return unpack_format(io, IntFixNegativeFormat(reinterpret(Int8, byte)), T) end invalid_unpack(io, byte, t, T) # should be unreachable, but ensures error is thrown if reached end unpack_format(io, f::IntFixPositiveFormat, ::Type{T}) where {T} = from_msgpack(T, UInt8(f.byte)) unpack_format(io, f::IntFixNegativeFormat, ::Type{T}) where {T} = from_msgpack(T, Int8(f.byte)) unpack_format(io, f::IntFixPositiveFormat, ::Type{T}) where {T<:Skip} = T() unpack_format(io, f::IntFixNegativeFormat, ::Type{T}) where {T<:Skip} = T() unpack_format(io, ::UInt8Format, ::Type{T}) where {T} = from_msgpack(T, read(io, UInt8)) unpack_format(io, ::UInt16Format, ::Type{T}) where {T} = from_msgpack(T, ntoh(read(io, UInt16))) unpack_format(io, ::UInt32Format, ::Type{T}) where {T} = from_msgpack(T, ntoh(read(io, UInt32))) unpack_format(io, ::UInt64Format, ::Type{T}) where {T} = from_msgpack(T, ntoh(read(io, UInt64))) unpack_format(io, ::UInt8Format, ::Type{T}) where {T<:Skip} = (skip(io, 1); T()) unpack_format(io, ::UInt16Format, ::Type{T}) where {T<:Skip} = (skip(io, 2); T()) unpack_format(io, ::UInt32Format, ::Type{T}) where {T<:Skip} = (skip(io, 4); T()) unpack_format(io, ::UInt64Format, ::Type{T}) where {T<:Skip} = (skip(io, 8); T()) unpack_format(io, ::Int8Format, ::Type{T}) where {T} = from_msgpack(T, read(io, Int8)) unpack_format(io, ::Int16Format, ::Type{T}) where {T} = from_msgpack(T, ntoh(read(io, Int16))) unpack_format(io, ::Int32Format, ::Type{T}) where {T} = from_msgpack(T, ntoh(read(io, Int32))) unpack_format(io, ::Int64Format, ::Type{T}) where {T} = from_msgpack(T, ntoh(read(io, Int64))) unpack_format(io, ::Int8Format, ::Type{T}) where {T<:Skip} = (skip(io, 1); T()) unpack_format(io, ::Int16Format, ::Type{T}) where {T<:Skip} = (skip(io, 2); T()) unpack_format(io, ::Int32Format, ::Type{T}) where {T<:Skip} = (skip(io, 4); T()) unpack_format(io, ::Int64Format, ::Type{T}) where {T<:Skip} = (skip(io, 8); T()) ##### ##### `NilType` ##### function unpack_type(io, byte, t::NilType, ::Type{T}; strict) where {T} byte === magic_byte(NilFormat) && return unpack_format(io, NilFormat(), T) invalid_unpack(io, byte, t, T) end unpack_type(io, byte, ::NilType, ::Type{T}; strict) where {T<:Skip} = T() unpack_format(io, ::NilFormat, ::Type{T}) where {T} = from_msgpack(T, nothing) ##### ##### `BooleanType` ##### function unpack_type(io, byte, t::BooleanType, ::Type{T}; strict) where {T} byte === magic_byte(TrueFormat) && return unpack_format(io, TrueFormat(), T) byte === magic_byte(FalseFormat) && return unpack_format(io, FalseFormat(), T) invalid_unpack(io, byte, t, T) end unpack_type(io, byte, ::BooleanType, ::Type{T}; strict) where {T<:Skip} = T() unpack_format(io, ::TrueFormat, ::Type{T}) where {T} = from_msgpack(T, true) unpack_format(io, ::FalseFormat, ::Type{T}) where {T} = from_msgpack(T, false) ##### ##### `FloatType` ##### function unpack_type(io, byte, t::FloatType, ::Type{T}; strict) where {T} if byte === magic_byte(Float32Format) return unpack_format(io, Float32Format(), T) elseif byte === magic_byte(Float64Format) return unpack_format(io, Float64Format(), T) else invalid_unpack(io, byte, t, T) end end unpack_format(io, ::Float32Format, ::Type{T}) where {T} = from_msgpack(T, ntoh(read(io, Float32))) unpack_format(io, ::Float32Format, ::Type{T}) where {T<:Skip} = (skip(io, 4); T()) unpack_format(io, ::Float64Format, ::Type{T}) where {T} = from_msgpack(T, ntoh(read(io, Float64))) unpack_format(io, ::Float64Format, ::Type{T}) where {T<:Skip} = (skip(io, 8); T()) ##### ##### `StringType` ##### function unpack_type(io, byte, t::StringType, ::Type{T}; strict) where {T} if byte <= magic_byte_max(StrFixFormat) return unpack_format(io, StrFixFormat(byte), T) elseif byte === magic_byte(Str8Format) return unpack_format(io, Str8Format(), T) elseif byte === magic_byte(Str16Format) return unpack_format(io, Str16Format(), T) elseif byte === magic_byte(Str32Format) return unpack_format(io, Str32Format(), T) else invalid_unpack(io, byte, t, T) end end unpack_format(io, ::Str8Format, ::Type{T}) where {T} = _unpack_string(io, read(io, UInt8), T) unpack_format(io, ::Str16Format, ::Type{T}) where {T} = _unpack_string(io, ntoh(read(io, UInt16)), T) unpack_format(io, ::Str32Format, ::Type{T}) where {T} = _unpack_string(io, ntoh(read(io, UInt32)), T) unpack_format(io, f::StrFixFormat, ::Type{T}) where {T} = _unpack_string(io, xor(f.byte, magic_byte_min(StrFixFormat)), T) _unpack_string(io, n, ::Type{T}) where {T} = from_msgpack(T, String(read(io, n))) _unpack_string(io, n, ::Type{T}) where {T<:Skip} = (skip(io, n); T()) # Below is a nice optimization we can apply when `io` wraps an indexable byte # buffer; this is really nice for skipping an extra copy when we deserialize # the field names of `T` where `msgpack_type(T)::MutableStruct`. Like much of # this package, this trick can be traced back to Jacob Quinn's magnificent # JSON3.jl! function _unpack_string(io::Base.GenericIOBuffer, n, ::Type{T}) where {T} result = from_msgpack(T, PointerString(pointer(io.data, io.ptr), n)) skip(io, n) return result end # necessary to resolve ambiguity _unpack_string(io::Base.GenericIOBuffer, n, ::Type{T}) where {T<:Skip} = (skip(io, n); T()) ##### ##### `BinaryType` ##### function unpack_type(io, byte, t::BinaryType, ::Type{T}; strict) where {T} if byte === magic_byte(Bin8Format) return unpack_format(io, Bin8Format(), T) elseif byte === magic_byte(Bin16Format) return unpack_format(io, Bin16Format(), T) elseif byte === magic_byte(Bin32Format) return unpack_format(io, Bin32Format(), T) else invalid_unpack(io, byte, t, T) end end unpack_format(io, ::Bin8Format, ::Type{T}) where {T} = _unpack_binary(io, read(io, UInt8), T) unpack_format(io, ::Bin16Format, ::Type{T}) where {T} = _unpack_binary(io, ntoh(read(io, UInt16)), T) unpack_format(io, ::Bin32Format, ::Type{T}) where {T} = _unpack_binary(io, ntoh(read(io, UInt32)), T) _unpack_binary(io, n, ::Type{T}) where {T} = from_msgpack(T, read(io, n)) _unpack_binary(io, n, ::Type{T}) where {T<:Skip} = (skip(io, n); T()) ##### ##### `ArrayType` ##### function unpack_type(io, byte, t::ArrayType, ::Type{T}; strict) where {T} if byte <= magic_byte_max(ArrayFixFormat) return unpack_format(io, ArrayFixFormat(byte), T, strict) elseif byte === magic_byte(Array16Format) return unpack_format(io, Array16Format(), T, strict) elseif byte === magic_byte(Array32Format) return unpack_format(io, Array32Format(), T, strict) else invalid_unpack(io, byte, t, T) end end unpack_format(io, ::Array16Format, ::Type{T}, strict) where {T} = _unpack_array(io, ntoh(read(io, UInt16)), T, strict) unpack_format(io, ::Array32Format, ::Type{T}, strict) where {T} = _unpack_array(io, ntoh(read(io, UInt32)), T, strict) unpack_format(io, f::ArrayFixFormat, ::Type{T}, strict) where {T} = _unpack_array(io, xor(f.byte, magic_byte_min(ArrayFixFormat)), T, strict) _eltype(T) = eltype(T) function _unpack_array(io, n, ::Type{T}, strict) where {T} E = _eltype(T) e = msgpack_type(E) result = Vector{E}(undef, n) for i in 1:n result[i] = unpack_type(io, read(io, UInt8), e, E; strict=strict) end return from_msgpack(T, result) end function _unpack_array(io, n, ::Type{Skip{T}}, strict) where {T} E = _eltype(T) e = msgpack_type(E) for _ in 1:n unpack_type(io, read(io, UInt8), e, Skip{E}; strict=strict) end return Skip{T}() end function _unpack_array(io, n, ::Type{T}, strict) where {N, T<:Tuple{Vararg{Any, N}}} return T(tuple(( unpack_type(io, read(io, UInt8), msgpack_type(fieldtype(T, i)), fieldtype(T, i); strict=strict) for i in 1:N )...)) end function _unpack_array(io, n, ::Type{Skip{T}}, strict) where {T<:Tuple} for i in 1:N unpack_type(io, read(io, UInt8), msgpack_type(fieldtype(T, i)), fieldtype(T, i); strict=strict) end return Skip{T}() end function _unpack_array(io::Base.GenericIOBuffer, n, ::Type{T}, strict) where {T<:ArrayView} E = _eltype(T) e = msgpack_type(E) start = position(io) positions = Vector{UInt64}(undef, n) for i in 1:length(positions) positions[i] = (position(io) - start) + 1 unpack_type(io, read(io, UInt8), e, Skip{E}; strict=strict) end bytes = view(io.data, (start + 1):position(io)) return ArrayView{E}(bytes, positions, strict) end ##### ##### `MapType` ##### function unpack_type(io, byte, t::MapType, ::Type{T}; strict) where {T} if byte <= magic_byte_max(MapFixFormat) return unpack_format(io, MapFixFormat(byte), T, strict) elseif byte === magic_byte(Map16Format) return unpack_format(io, Map16Format(), T, strict) elseif byte === magic_byte(Map32Format) return unpack_format(io, Map32Format(), T, strict) else invalid_unpack(io, byte, t, T) end end unpack_format(io, ::Map16Format, ::Type{T}, strict) where {T} = _unpack_map(io, ntoh(read(io, UInt16)), T, strict) unpack_format(io, ::Map32Format, ::Type{T}, strict) where {T} = _unpack_map(io, ntoh(read(io, UInt32)), T, strict) unpack_format(io, f::MapFixFormat, ::Type{T}, strict) where {T} = _unpack_map(io, xor(f.byte, magic_byte_min(MapFixFormat)), T, strict) _keytype(T) = Any _keytype(::Type{T}) where {K,V,T<:AbstractDict{K,V}} = keytype(T) _valtype(T) = Any _valtype(::Type{T}) where {K,V,T<:AbstractDict{K,V}} = valtype(T) function _unpack_map(io, n, ::Type{T}, strict) where {T} K = _keytype(T) k = msgpack_type(K) V = _valtype(T) v = msgpack_type(V) dict = Dict{K,V}() for _ in 1:n key = unpack_type(io, read(io, UInt8), k, K; strict=strict) val = unpack_type(io, read(io, UInt8), v, V; strict=strict) dict[key] = val end return from_msgpack(T, dict) end function _unpack_map(io, n, ::Type{Skip{T}}, strict) where {T} K = _keytype(T) k = msgpack_type(K) V = _valtype(T) v = msgpack_type(V) for i in 1:n unpack_type(io, read(io, UInt8), k, Skip{K}; strict=strict) unpack_type(io, read(io, UInt8), v, Skip{V}; strict=strict) end return Skip{T}() end function _unpack_map(io::Base.GenericIOBuffer, n, ::Type{T}, strict) where {T<:MapView} K = _keytype(T) k = msgpack_type(K) V = _valtype(T) v = msgpack_type(V) start = position(io) positions = Dict{K,UnitRange{UInt64}}() for _ in 1:n key = unpack_type(io, read(io, UInt8), k, K; strict=strict) value_start = (position(io) - start) + 1 unpack_type(io, read(io, UInt8), v, Skip{V}; strict=strict) positions[key] = value_start:(position(io) - start) end bytes = view(io.data, (start + 1):position(io)) return MapView{K,V}(bytes, positions, strict) end ##### ##### `ExtensionType` ##### function unpack_type(io, byte, t::ExtensionType, ::Type{T}; strict) where {T} byte === magic_byte(ExtFix1Format) && return unpack_format(io, ExtFix1Format(), T) byte === magic_byte(ExtFix2Format) && return unpack_format(io, ExtFix2Format(), T) byte === magic_byte(ExtFix4Format) && return unpack_format(io, ExtFix4Format(), T) byte === magic_byte(ExtFix8Format) && return unpack_format(io, ExtFix8Format(), T) byte === magic_byte(ExtFix16Format) && return unpack_format(io, ExtFix16Format(), T) byte === magic_byte(Ext8Format) && return unpack_format(io, Ext8Format(), T) byte === magic_byte(Ext16Format) && return unpack_format(io, Ext16Format(), T) byte === magic_byte(Ext32Format) && return unpack_format(io, Ext32Format(), T) invalid_unpack(io, byte, t, T) end unpack_format(io, ::ExtFix1Format, ::Type{T}) where {T} = _unpack_extension(io, 1, T) unpack_format(io, ::ExtFix2Format, ::Type{T}) where {T} = _unpack_extension(io, 2, T) unpack_format(io, ::ExtFix4Format, ::Type{T}) where {T} = _unpack_extension(io, 4, T) unpack_format(io, ::ExtFix8Format, ::Type{T}) where {T} = _unpack_extension(io, 8, T) unpack_format(io, ::ExtFix16Format, ::Type{T}) where {T} = _unpack_extension(io, 16, T) unpack_format(io, ::Ext8Format, ::Type{T}) where {T} = _unpack_extension(io, read(io, UInt8), T) unpack_format(io, ::Ext16Format, ::Type{T}) where {T} = _unpack_extension(io, ntoh(read(io, UInt16)), T) unpack_format(io, ::Ext32Format, ::Type{T}) where {T} = _unpack_extension(io, ntoh(read(io, UInt32)), T) function _unpack_extension(io, n, ::Type{T}) where {T} type = read(io, Int8) data = read(io, n) return from_msgpack(T, Extension(type, data)) end ##### ##### utilities ##### @noinline function invalid_unpack(io, byte, m, T) error("invalid byte $(repr(byte)) encountered in $(io) attempting to read a MsgPack $(m) into a Julia $(T) at position $(position(io))") end -/opt/julia/packages/MsgPack/LleAi/src/pack.jl"(""" pack(x) Serialize `x` to MessagePack format and return the resulting `Vector{UInt8}`. This function uses [`msgpack_type`](@ref) and [`to_msgpack`](@ref) to determine the appropriate translation of the `value` into MessagePack format. See also: [`unpack`](@ref) """ function pack(x) io = IOBuffer(UInt8[]; append = true) pack(io, x) return take!(io) end """ pack(io::IO, x) Like `pack(x)`, but write the resulting bytes to `io`. Returns `nothing`. See also: [`unpack`](@ref) """ function pack(io::IO, x) pack_type(io, msgpack_type(typeof(x)), x) return nothing end ##### ##### `AnyType` ##### # This function might've been reached via another `pack_type` method that # relied on reflection and ended up calling `msgpack_type` on a type that # didn't have a non-`AnyType` mapping, even if the underlying value it's trying # serialize does (e.g. an object field with a `Union` type). Thus, before giving # up, we first attempt to resolve the issue by calling `msgpack_type(typeof(x))` # directly. function pack_type(io, t::AnyType, x) tx = msgpack_type(typeof(x)) if tx isa AnyType error("no non-`AnyType` MsgPack mapping found for ", typeof(x), "; please ", "overload `msgpack_type` for this type.") end return pack_type(io, tx, x) end ##### ##### `StructType` ##### function pack_type(io, t::StructType, x::T) where {T} N = fieldcount(T) if N <= 15 write(io, magic_byte_min(MapFixFormat) | UInt8(N)) elseif N <= typemax(UInt16) write(io, magic_byte(Map16Format)) write(io, hton(UInt16(N))) elseif N <= typemax(UInt32) write(io, magic_byte(Map32Format)) write(io, hton(UInt32(N))) else invalid_pack(io, t, x) end Base.@nexprs 32 i -> begin F_i = fieldtype(T, i) pack_type(io, StringType(), fieldname(T, i)) pack_type(io, msgpack_type(fieldtype(T, i)), getfield(x, i)) N == i && return nothing end for i in 33:N F_i = fieldtype(T, i) pack_type(io, StringType(), fieldname(T, i)) pack_type(io, msgpack_type(fieldtype(T, i)), getfield(x, i)) end return nothing end ##### ##### `IntegerType` ##### function pack_type(io, t::IntegerType, x) x = to_msgpack(t, x) if x < 0 x >= -32 && return pack_format(io, IntFixNegativeFormat(Int8(x))) x >= typemin(Int8) && return pack_format(io, Int8Format(), x) x >= typemin(Int16) && return pack_format(io, Int16Format(), x) x >= typemin(Int32) && return pack_format(io, Int32Format(), x) x >= typemin(Int64) && return pack_format(io, Int64Format(), x) else x <= 127 && return pack_format(io, IntFixPositiveFormat(UInt8(x))) x <= typemax(UInt8) && return pack_format(io, UInt8Format(), x) x <= typemax(UInt16) && return pack_format(io, UInt16Format(), x) x <= typemax(UInt32) && return pack_format(io, UInt32Format(), x) x <= typemax(UInt64) && return pack_format(io, UInt64Format(), x) end invalid_pack(io, t, x) end pack_format(io, f::Union{IntFixNegativeFormat,IntFixPositiveFormat}) = write(io, f.byte) pack_format(io, f::Int8Format, x) = _pack_integer(io, f, Int8, x) pack_format(io, f::Int16Format, x) = _pack_integer(io, f, Int16, x) pack_format(io, f::Int32Format, x) = _pack_integer(io, f, Int32, x) pack_format(io, f::Int64Format, x) = _pack_integer(io, f, Int64, x) pack_format(io, f::UInt8Format, x) = _pack_integer(io, f, UInt8, x) pack_format(io, f::UInt16Format, x) = _pack_integer(io, f, UInt16, x) pack_format(io, f::UInt32Format, x) = _pack_integer(io, f, UInt32, x) pack_format(io, f::UInt64Format, x) = _pack_integer(io, f, UInt64, x) function _pack_integer(io, ::F, ::Type{T}, x) where {F,T} y = hton(T(x)) write(io, magic_byte(F)) write(io, y) end ##### ##### `NilType` ##### pack_type(io, ::NilType, x) = pack_format(io, NilFormat(), x) pack_format(io, ::NilFormat, ::Any) = write(io, magic_byte(NilFormat)) ##### ##### `BooleanType` ##### function pack_type(io, t::BooleanType, x) x = to_msgpack(t, x) x == true && return pack_format(io, TrueFormat(), x) x == false && return pack_format(io, FalseFormat(), x) invalid_pack(io, t, x) end pack_format(io, ::TrueFormat, ::Any) = write(io, magic_byte(TrueFormat)) pack_format(io, ::FalseFormat, ::Any) = write(io, magic_byte(FalseFormat)) ##### ##### `FloatType` ##### function pack_type(io, t::FloatType, x) x = to_msgpack(t, x) x isa Float32 && return pack_format(io, Float32Format(), x) x isa Float64 && return pack_format(io, Float64Format(), x) invalid_pack(io, t, x) end function pack_format(io, ::Float32Format, x) y = Float32(x) write(io, magic_byte(Float32Format)) write(io, hton(y)) end function pack_format(io, ::Float64Format, x) y = Float64(x) write(io, magic_byte(Float64Format)) write(io, hton(y)) end ##### ##### `StringType` ##### function pack_type(io, t::StringType, x) x = to_msgpack(t, x) n = x isa PointerString ? x.len : sizeof(x) n <= 31 && return pack_format(io, StrFixFormat(magic_byte_min(StrFixFormat) | UInt8(n)), x) n <= typemax(UInt8) && return pack_format(io, Str8Format(), x) n <= typemax(UInt16) && return pack_format(io, Str16Format(), x) n <= typemax(UInt32) && return pack_format(io, Str32Format(), x) invalid_pack(io, t, x) end function pack_format(io, f::StrFixFormat, x) write(io, f.byte) write(io, x) end function pack_format(io, ::Str8Format, x) write(io, magic_byte(Str8Format)) write(io, UInt8(sizeof(x))) write(io, x) end function pack_format(io, ::Str16Format, x) write(io, magic_byte(Str16Format)) write(io, hton(UInt16(sizeof(x)))) write(io, x) end function pack_format(io, ::Str32Format, x) write(io, magic_byte(Str32Format)) write(io, hton(UInt32(sizeof(x)))) write(io, x) end ##### ##### `BinaryType` ##### function pack_type(io, t::BinaryType, x) x = to_msgpack(t, x) n = length(x) n <= typemax(UInt8) && return pack_format(io, Bin8Format(), x) n <= typemax(UInt16) && return pack_format(io, Bin16Format(), x) n <= typemax(UInt32) && return pack_format(io, Bin32Format(), x) invalid_pack(io, t, x) end function pack_format(io, ::Bin8Format, x) write(io, magic_byte(Bin8Format)) write(io, UInt8(length(x))) write(io, x) end function pack_format(io, ::Bin16Format, x) write(io, magic_byte(Bin16Format)) write(io, hton(UInt16(length(x)))) write(io, x) end function pack_format(io, ::Bin32Format, x) write(io, magic_byte(Bin32Format)) write(io, hton(UInt32(length(x)))) write(io, x) end ##### ##### `ArrayType` ##### function pack_type(io, t::ArrayType, x) x = to_msgpack(t, x) n = length(x) n <= 15 && return pack_format(io, ArrayFixFormat(magic_byte_min(ArrayFixFormat) | UInt8(n)), x) n <= typemax(UInt16) && return pack_format(io, Array16Format(), x) n <= typemax(UInt32) && return pack_format(io, Array32Format(), x) invalid_pack(io, t, x) end function pack_format(io, f::ArrayFixFormat, x) write(io, f.byte) for i in x pack(io, i) end end function pack_format(io, ::Array16Format, x) write(io, magic_byte(Array16Format)) write(io, hton(UInt16(length(x)))) for i in x pack(io, i) end end function pack_format(io, ::Array32Format, x) write(io, magic_byte(Array32Format)) write(io, hton(UInt32(length(x)))) for i in x pack(io, i) end end ##### ##### `MapType` ##### function pack_type(io, t::MapType, x) x = to_msgpack(t, x) n = length(x) n <= 15 && return pack_format(io, MapFixFormat(magic_byte_min(MapFixFormat) | UInt8(n)), x) n <= typemax(UInt16) && return pack_format(io, Map16Format(), x) n <= typemax(UInt32) && return pack_format(io, Map32Format(), x) invalid_pack(io, t, x) end function pack_format(io, f::MapFixFormat, x) write(io, f.byte) for (k, v) in x pack(io, k) pack(io, v) end end function pack_format(io, ::Map16Format, x) write(io, magic_byte(Map16Format)) write(io, hton(UInt16(length(x)))) for (k, v) in x pack(io, k) pack(io, v) end end function pack_format(io, ::Map32Format, x) write(io, magic_byte(Map32Format)) write(io, hton(UInt32(length(x)))) for (k, v) in x pack(io, k) pack(io, v) end end ##### ##### `ExtensionType` ##### function pack_type(io, t::ExtensionType, x) ext = to_msgpack(t, x)::Extension nbytes = sizeof(ext.data) write_extension_header(io, nbytes, ext.type) write(io, ext.data) end function extformat_from_bytes(nbytes::Int) nbytes == 1 && return ExtFix1Format() nbytes == 2 && return ExtFix2Format() nbytes == 4 && return ExtFix4Format() nbytes == 8 && return ExtFix8Format() nbytes == 16 && return ExtFix16Format() nbytes <= typemax(UInt8) && return Ext8Format() nbytes <= typemax(UInt16) && return Ext16Format() nbytes <= typemax(UInt32) && return Ext32Format() error("Object is too big to fit byte size into UInt32") end const ExtFixFormat = Union{ExtFix1Format,ExtFix2Format,ExtFix4Format,ExtFix8Format,ExtFix16Format} write_size(io, ::ExtFixFormat, nbytes) = nothing # Fixed format doesn't write the size write_size(io, ::Ext8Format, nbytes) = write(io, UInt8(nbytes)) write_size(io, ::Ext16Format, nbytes) = write(io, hton(UInt16(nbytes))) write_size(io, ::Ext32Format, nbytes) = write(io, hton(UInt32(nbytes))) write_sizeof(::ExtFixFormat) = 0 # Fixed format doesn't write the size write_sizeof(::Ext8Format) = sizeof(UInt8) write_sizeof(::Ext16Format) = sizeof(UInt16) write_sizeof(::Ext32Format) = sizeof(UInt32) function write_extension_header(io::IO, nbytes::Int, type::Int8) f = extformat_from_bytes(nbytes) write(io, magic_byte(typeof(f))) write_size(io, f, nbytes) write(io, type) end function ext_header_size(nbytes::Int) f = extformat_from_bytes(nbytes) return sizeof(magic_byte(typeof(f))) + write_sizeof(f) + sizeof(Int8) end ##### ##### utilities ##### @noinline function invalid_pack(io, t, x) error("cannot serialize Julia value $(x) with type $(typeof(x)) as MsgPack type $(t) to $(io)") end Hwvu