[英]How to ignore Codec after using it to limit size bytes
I would create a model for the KMIP protocols that works with TTLV encoding ( Tag, Type, Length, Value ) 我将为使用TTLV编码( 标记,类型,长度,值 )的KMIP协议创建一个模型。
The ttlv
function is "high level" and accepts the tag, the type and the codec of the value. ttlv
函数是“高级”的,它接受值的标签,类型和编解码器。
def ttlv[A<:HList](tag:ByteVector, itype:ByteVector, value: Codec[A]) =
constant(tag) :: constant(itype) ::
(uint32 >>:~ {
case length => limitedSizeBytes(length, value)
})
The result is a Codec[Unit :: Unit :: Long :: A]
. 结果是
Codec[Unit :: Unit :: Long :: A]
。 However, I would have a Codec[Unit :: Unit :: Unit :: A]
(or Codec[A]
) to cast the codec to a case class
with only the value A
. 但是,我会有一个
Codec[Unit :: Unit :: Unit :: A]
(或Codec[A]
)将编解码器转换为仅包含值A
的case class
。 How to ignore the uint32
after used by limitedSizeBytes
? 由
limitedSizeBytes
使用后如何忽略uint32
? Otherwise I am interested for comments for better approaches. 否则,我有兴趣寻求更好的方法的意见。
Here are case class
examples: 以下是
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)
More high level functions like ttlvStructure
更多高级功能,如
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)
And the final codec: 最后的编解码器:
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]
Example of object to encode: 编码对象的示例:
val m = RequestMessage(
RequestHeader(14),
RequestPayload(
CompromiseDate(8),
CertificateName("certificate name")
)
)
Solution : 解决方案 :
variableSizeBytesLong
is here to do what I want: variableSizeBytesLong
在这里是我想要做的:
def ttlv[A<:HList](tag:ByteVector, itype:ByteVector, value: Codec[A]): Codec[A] =
(constant(tag) :~>: constant(itype) :~>: variableSizeBytesLong(uint32, value))
Try 尝试
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 :: _)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.