Scodec:将vectorOfN与vlong字段一起使用

时间:2017-12-10 11:22:42

标签: scala scodec

我正在玩比特币区块链来学习Scala和一些有用的库。 目前我正在尝试使用SCodec解码和编码块,我的问题是vectorOfN函数将其大小作为Int。如何在仍然保留整个值范围的同时使用长字段。 换句话说,是否有vectorOfLongN函数?

这是我的代码,如果我使用的是vintL而不是vlongL,则可以正常编译:

object Block {
  implicit val codec: Codec[Block] = {
    ("header" | Codec[BlockHeader]) ::
    (("numTx" | vlongL) >>:~
      { numTx => ("transactions" | vectorOfN(provide(numTx), Codec[Transaction]) ).hlist })
  }.as[Block]
}

您可以假设实施了适用于Blockheader和Transactions的编解码器。实际上,vlong被用作这个问题的简化,因为比特币使用自己的编解码器来实现可变大小的整数。

2 个答案:

答案 0 :(得分:0)

我不是scodec专家,但我的常识表明这是不可能的,因为Scala的VectorGenSeqLike的子类型仅限于length类型Int接受apply索引作为参数的{}和Int。而AFAIU此限制来自底层JVM平台,您不能拥有大于Integer.MAX_VALUE的大小数组,即大约2 ^ 31(另请参阅"Criticism of Java" wiki)。虽然Vector理论上可以解决这个问题,但是没有做到。因此vectorOfN支持Long大小也毫无意义。

换句话说,如果你想要这样的东西,你可能应该从创建你自己的类似于类的类开始,它支持解决JVM限制的Long索引。

答案 1 :(得分:0)

您可能需要查看scodec-stream,当您的所有数据无法立即显示或无法存储到内存中时,这会派上用场。

基本上,您可以使用通常的codecs.X并通过StreamDecoder将其转换为scodec.stream.decode.many(normal_codec)。这样,您就可以通过scodec处理数据,而无需将其完全加载到内存中。

StreamDecoder然后decodeInputStream通常会scodec's提供decode等方法。

(我刚才在稍微不同的上下文中使用它 - 解析客户端发送到服务器的数据 - 但看起来它也适用于此处。)