首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >scodec variableSizePrefixBytes变换

scodec variableSizePrefixBytes变换
EN

Stack Overflow用户
提问于 2016-01-05 16:10:45
回答 1查看 321关注 0票数 3

我有一个用例,其中一个头可以包含7个字节加上一个可选的0-15字节的信息,其中的大小信息位于第5字节的较低的4位,所以格式是:

代码语言:javascript
复制
4 bytes | 4 bits | 4 bits <- length of extra bytes | 2 bytes | 0-15 extra Bytes

我在下面的案例类中对此进行了建模

代码语言:javascript
复制
case class FHDR(DevAddr:Long, ADR:Boolean, ADRACKReq:Boolean, ACK:Boolean, FPending:Boolean, FCnt:Int, FOpts:ByteVector)

implicit val FHDRCodec = {
  ("dev_addr" | uint32L) ::
  ("adr" | bool) ::
  ("adr_ack_req" | bool) ::
  ("ack" | bool) ::
  ("f_pending" | bool) ::
  variableSizePrefixedBytes(uint4, 
    "f_cnt" | uint16L, 
    "f_opts" | bytes)
}.as[FHDR]

根据scala,在本例中,我可以使用variableSizePrefixedBytes方法对大小和额外字节之间的2个额外字节进行建模。

但是我做错了一些事情,因为编译器不能证明这个编解码器可以转换为/从FHDR类,我已经盯着这个看了很长一段时间了,但我毫无头绪

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-05 17:35:22

本例中的错误是:

代码语言:javascript
复制
error: Could not prove that shapeless.::[Long,shapeless.::[Boolean,shapeless.::[Boolean,shapeless.::[Boolean,shapeless.::[Boolean,shapeless.::[(Int, scodec.bits.ByteVector),shapeless.HNil]]]]]] can be converted to/from FHDR.
   }.as[FHDR]
       ^

将错误重新格式化为在infix位置使用::提供如下信息:

代码语言:javascript
复制
error: Could not prove that Long :: Boolean :: Boolean :: Boolean :: Boolean :: (Int, ByteVector) :: HNil can be converted to/from FHDR.
   }.as[FHDR]
       ^

FHDR的泛型表示形式是Long :: Boolean :: Boolean :: Boolean :: Boolean :: Int :: ByteVector :: HNil。这里的问题是,HList中的最后一个类型是(Int, ByteVector),它是由具有以下签名的variableSizePrefixedBytes引起的:

代码语言:javascript
复制
  def variableSizePrefixedBytes[A, B](size: Codec[Int], prefix: Codec[A], value: Codec[B], sizePadding: Int = 0): Codec[(A, B)] = ...

我们需要将该元组简化为外部HList结构,这将导致编解码器的形状与FHDR的泛型表示形式相匹配。

代码语言:javascript
复制
import scodec.bits._
import scodec.codecs._
import shapeless.syntax.std.product._

case class FHDR(DevAddr:Long, ADR:Boolean, ADRACKReq:Boolean, ACK:Boolean, FPending:Boolean, FCnt:Int, FOpts:ByteVector)

implicit val FHDRCodec = {
  ("dev_addr" | uint32L) ::
  ("adr" | bool) ::
  ("adr_ack_req" | bool) ::
  ("ack" | bool) ::
  ("f_pending" | bool) ::
  variableSizePrefixedBytes(uint4, 
    "f_cnt" | uint16L, 
    "f_opts" | bytes
  ).xmapc(_.toHList)(_.tupled)
}.as[FHDR]

在这里,我们在来自.toHList导入的Tuple2上使用shapeless.syntax.std.product._。我们还使用.tupled来逆转这种转换。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34616166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档