API Reference
ProtocolDataUnits.AbstractPDU
— TypeParent data type for all PDUs.
ProtocolDataUnits.byteorder
— Functionbyteorder(::Type{T})
Byte order used for PDUs of type T
. Defaults to BIG_ENDIAN
. To change byte order, define a method for this function.
Example:
PDU.byteorder(::Type{MyPDU}) = LITTLE_ENDIAN
byteorder(::Type{T}, ::Val{s})
Byte order used for PDUs of type T
for field s
. Defaults to the same byte order as the PDU. To change byte order, define a method for this function.
Example:
PDU.byteorder(::Type{MyPDU}, ::Val{:myfield}) = LITTLE_ENDIAN
Base.length
— Methodlength(::Type{T}, ::Val{s}, info::PDUInfo)
Length of field s
in PDU of type T
. Defaults to nothing
(unknown) for vectors, and WireEncoded()
(stored in the PDU) for strings. The length is specified in number of elements for vectors, and number of bytes for strings.
Examples:
# length of field x is 4 bytes less than length of PDU
Base.length(::Type{MyPDU}, ::Val{:x}, info) = info.length - 4
# length of field x is given by the value of field n in the PDU
Base.length(::Type{MyPDU}, ::Val{:x}, info) = info.get(:n)
# length of field x is 16, and is zero-padded to size if necessary
Base.length(::Type{MyPDU}, ::Val{:x}, info) = PadTo(16)
# length of field x is variable and stored in the PDU using wire-encoding
Base.length(::Type{MyPDU}, ::Val{:x}, info) = WireEncoded()
ProtocolDataUnits.fieldtype
— Functionfieldtype(::Type{T}, ::Val{s}, info::PDUInfo)
Concrete type of field s
in PDU of type T
. Defaults to the type of the field in the PDU. To specialize the type based on auxillary information in the PDU, define a method for this function.
Example:
# field x::Union{Int32,Int64} is Int32 if xtype is 4, Int64 otherwise
PDU.fieldtype(::Type{MyPDU}, ::Val{:x}, info) = info.get(:xtype) == 4 ? Int32 : Int64
ProtocolDataUnits.PDUInfo
— TypePDU information with fields:
length
: length of PDU in bytes, if known,missing
otherwiseget
: function that returns value of fields
in the PDU
ProtocolDataUnits.encode
— MethodPDU.encode(pdu::AbstractPDU; hooks=true)
Encodes a PDU into a vector of bytes. If hooks
is true
, the pre-encode hook is called before encoding the PDU.
ProtocolDataUnits.decode
— MethodPDU.decode(buf::Vector{UInt8}, T::Type{<:AbstractPDU}; hooks=true)
Decodes a vector of bytes to give a PDU. If hooks
is true
, the post-decode hook is called after decoding the PDU.
Base.read
— Methodread(io::IO, T::AbstractPDU; hooks=true)
read(io::IO, T::AbstractPDU; nbytes, hooks=true)
Decodes a vector of bytes from stream io
to give a PDU. If nbytes
is specified, the PDU is assumed to be of length nbytes
bytes. If hooks
is true
, the post-decode hook is called after decoding the PDU.
Base.write
— Methodwrite(io::IO, pdu::AbstractPDU; hooks=true)
Encodes a PDU into a vector of bytes written to stream io
. If hooks
is true
, the pre-encode hook is called before encoding the PDU.
ProtocolDataUnits.preencode
— Functionpreencode(pdu::AbstractPDU)
Pre-encode hook. This function is called before encoding a PDU into a vector of bytes. It may return a new PDU, which is then encoded instead of the original PDU. The pre-encode hook should not change the type of the PDU.
Example:
using Accessors, CRC32
# assumes MyPDU has field crc::UInt32 as the last field
function PDU.preencode(pdu::MyPDU)
bytes = Vector{UInt8}(pdu; hooks=false)
crc = crc32(bytes[1:end-4])
@set pdu.crc = crc
end
ProtocolDataUnits.postdecode
— Functionpostdecode(pdu::AbstractPDU)
Post-decode hook. This function is called after decoding a PDU from a vector of bytes. It may return a new PDU, which is then returned instead of the original PDU. The post-decode hook should not change the type of the PDU. The post-decode hook may also be used to validate the PDU, and throw an error if the PDU is invalid.
Example:
using CRC32
# assumes MyPDU has field crc::UInt32 as the last field
function PDU.postdecode(pdu::MyPDU)
bytes = Vector{UInt8}(pdu; hooks=false)
pdu.crc == crc32(bytes[1:end-4]) || throw(ErrorException("CRC check failed"))
pdu
end