Scala 解码未对齐值后的字节对齐位向量

Scala 解码未对齐值后的字节对齐位向量,scala,scodec,Scala,Scodec,我遇到了一个与scodec有关的有趣问题。我有一个特殊的编码方案,当当前位指针mod 8不为零(未与最近的字节对齐)时,需要流字节对齐 现在通常情况下,这将由byteAligned编解码器处理,但这种情况似乎需要整个解码操作的全局上下文 下面是这个问题的一个小例子 case class Baz(abc : Int, qux : Int) case class Foo(bar : Int, items : Vector[Baz]) object Foo {

我遇到了一个与scodec有关的有趣问题。我有一个特殊的编码方案,当当前位指针mod 8不为零(未与最近的字节对齐)时,需要流字节对齐

现在通常情况下,这将由
byteAligned
编解码器处理,但这种情况似乎需要整个解码操作的全局上下文

下面是这个问题的一个小例子

case class Baz(abc : Int, qux : Int)  
case class Foo(bar : Int,
               items : Vector[Baz])

object Foo {
   implicit val codec : Codec[Foo] = (
      ("bar" | uint8L) ::
      ("items" | vectorOfN(uint8L, (
            ("abc" | uint8L) ::
            ("qux" | uint2L)
         ).as[Baz]
      ))).as[Foo]
}
项目
将作为
Baz
项目的
向量
进行编码和解码。请注意,
Baz
中的
qux
成员表示为2位无符号整数。我们希望
abc
成员是字节对齐的,这意味着在解码期间,它将解码,如果字节流未对齐,则必须在解码位之后添加填充(情况C)

这意味着对于大小为1的向量(情况a),输出位向量将偏移6位,这是好的,因为没有更多的项(
abc
在向量解码循环中永远不会再次到达)

案例B中显示了大小为2且没有字节对齐的向量。 案例C中显示了字节对齐的向量

在每种情况下,注释都会分解比特流
0x0a
是十六进制表示10位小数,
0b01
是二进制表示1位小数。当需要更多细节和流没有字节对齐时,我将在两者之间切换

案例A

Codec.encode(Foo(10, Vector(Baz(4,1))))
res43: Attempt[BitVector] = Successful(BitVector(26 bits, 0x0a01044))
// bar  N items   abc(0)  qux(0)
// 0x0a   0x01     0x04    0b01   
案例B

Codec.encode(Foo(10, Vector(Baz(4,1), Baz(15,3))))
res42: Attempt[BitVector] = Successful(BitVector(36 bits, 0x0a020443f))
// bar  N items   abc(0)  qux(0)    abc(1)    qux(1)
// 0x0a   0x02     0x04    0b01   0b00001111   0b11 
案例C

Codec.encode(Foo(10, Vector(Baz(4,1), Baz(15,3))))
res42: Attempt[BitVector] = Successful(BitVector(42 bits, 0x0a020443c0c))
// bar  N items   abc(0)  qux(0)    abc(1)    padding   qux(1)
// 0x0a   0x02     0x04    0b01   0b00001111  0b000000   0b11 
查看案例C的另一种方法是展开编解码器

// bar     N items   abc(0)     qux(0)   abc(1)    padding       qux(1)
(uint8L :: uint8L :: uint8L :: uint2L :: uint8L :: ignore(6) :: uint2L).
   dropUnits.encode(10 :: 2 :: 4 :: 1 :: 15 :: 3 :: HNil)
res47: Attempt[BitVector] = Successful(BitVector(42 bits, 0x0a020443c0c))
请注意,
abc(0)
之后没有任何填充,因为流在该点是字节对齐的。在
abc(1)
处,由于
qux(0)
的解码,它没有对齐。对齐后,
qux
将在对齐的边界上解码。我们总是希望
qux
在字节对齐的位置进行解码

我需要的是某种方法来获取全局上下文,以确定整个位向量中的当前位指针是否对齐。如果没有,我需要一个编解码器来智能地知道它何时没有在对齐的边界上解码,并在解码流的当前值后纠正它

我知道编解码器可以获取当前要解码的比特流,但他们不知道它们在整个比特流中的位置

任何指示或代码都将不胜感激

p.S.

如果你想在Ammonite中测试,你需要这个来开始

load.ivy("org.scodec" %% "scodec-core" % "1.8.3")
import scodec.codecs._
import scodec._
import shapeless._ 
复制和粘贴时,需要从
{
开始,以确保同时定义case类和case对象