Как игнорировать кодек после его использования для ограничения размера байтов - PullRequest
0 голосов
/ 08 октября 2018

Я бы создал модель для протоколов KMIP, которая работает с кодировкой TTLV ( Метка, тип, длина, значение )

Функция 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 только со значением 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 здесь, чтобы делать то, что я хочу:

def ttlv[A<:HList](tag:ByteVector, itype:ByteVector, value: Codec[A]): Codec[A] =
    (constant(tag) :~>: constant(itype) :~>: variableSizeBytesLong(uint32, value))

1 Ответ

0 голосов
/ 08 октября 2018

Попробуйте

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 :: _)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...