我将为适用于TTLV编码(Tag, Type, Length, Value)的KMIP协议创建一个模型
ttlv
函数是“高级”的,它接受值的标记,类型和编解码器。
def ttlv[A<:HList](tag:ByteVector, itype:ByteVector, value: Codec[A]) =
constant(tag) :: constant(itype) ::
(uint32 >>:~ {
case length => limitedSizeBytes(length, value)
})
结果为Codec[Unit :: Unit :: Long :: A]
。但是,我将使用Codec[Unit :: Unit :: Unit :: A]
(或Codec[A]
)将编解码器转换为仅具有值case class
的{{1}}。 A
使用后如何忽略uint32
?否则,我会对改进方法的评论感兴趣。
以下是limitedSizeBytes
个示例:
case class
更多高级功能,例如case class RequestHeader(protocol:Int)
case class RequestPayload(payload:CompromiseDate, name:CertificateName)
case class RequestMessage(header:RequestHeader, payload: RequestPayload)
case class CompromiseDate(value:Int)
case class CertificateName(value:String)
ttlvStructure
最后一个编解码器:
def ttlvStructure[A<:HList](tag:ByteVector, struct:Codec[A]) =
ttlv(tag, hex"01", struct)
def ttlvTextString(tag:ByteVector) =
ttlv(tag, hex"07", utf8.hlist)
def ttlvInt(tag:ByteVector) =
ttlv(tag, hex"02", int32.hlist)
要编码的对象示例:
implicit val certificateNameCodec =
ttlvTextString(hex"420020").as[CertificateName]
implicit val compromiseDateCodec =
ttlvInt(hex"420021").as[CompromiseDate]
implicit val requestPayloadCodec =
ttlvStructure(hex"420003", Codec[CompromiseDate] :: Codec[CertificateName]).as[RequestPayload]
implicit val requestHeaderCodec =
ttlvInt(hex"420002").as[RequestHeader]
implicit val requestMessageCodec =
ttlvStructure(hex"420001", Codec[RequestHeader] :: Codec[RequestPayload]).as[RequestMessage]
解决方案:
val m = RequestMessage(
RequestHeader(14),
RequestPayload(
CompromiseDate(8),
CertificateName("certificate name")
)
)
在这里是我想要做的:
variableSizeBytesLong
答案 0 :(得分:1)
尝试
val defaultLength: Long = ???
def ttlv[A<:HList](tag:ByteVector, itype:ByteVector, value: Codec[A]): Codec[A] =
constant(tag) :~>: constant(itype) :~>:
(uint32 >>:~ (length => limitedSizeBytes(length, value))).xmap[A](_.tail, defaultLength :: _)