API Reference

ProtocolDataUnits.byteorderFunction
byteorder(::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
source
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
source
Base.lengthMethod
length(::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()
source
ProtocolDataUnits.fieldtypeFunction
fieldtype(::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
source
ProtocolDataUnits.PDUInfoType

PDU information with fields:

  • length: length of PDU in bytes, if known, missing otherwise
  • get: function that returns value of field s in the PDU
source
ProtocolDataUnits.encodeMethod
PDU.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.

source
ProtocolDataUnits.decodeMethod
PDU.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.

source
Base.readMethod
read(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.

source
Base.writeMethod
write(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.

source
ProtocolDataUnits.preencodeFunction
preencode(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
source
ProtocolDataUnits.postdecodeFunction
postdecode(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
source