Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions boopickle/shared/src/main/scala/boopickle/Pickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -326,25 +326,36 @@ object BasicPicklers extends PicklerHelper with XCompatPicklers {
}

override def unpickle(implicit state: UnpickleState): Array[T] = {
state.dec.readRawInt match {
val ct = implicitly[ClassTag[T]]
val len = state.dec.readRawInt

len match {
case NullRef =>
null

case _ if ct == ClassTag.Double =>
// Double arrays have an extra padding word for alignment.
// Consume it even when the array is empty, otherwise the decoder
// gets out of sync for the following fields.
state.dec.readRawInt
if (len == 0)
Array.emptyDoubleArray.asInstanceOf[Array[T]]
else
state.dec.readDoubleArray(len).asInstanceOf[Array[T]]

case 0 =>
// empty Array
Array.empty[T]
case len =>
val r = implicitly[ClassTag[T]] match {

case _ =>
ct match {
// handle specialization
case ClassTag.Byte =>
state.dec.readByteArray(len).asInstanceOf[Array[T]]
case ClassTag.Int =>
state.dec.readIntArray(len).asInstanceOf[Array[T]]
case ClassTag.Float =>
state.dec.readFloatArray(len).asInstanceOf[Array[T]]
case ClassTag.Double =>
// remove padding
state.dec.readRawInt
state.dec.readDoubleArray(len).asInstanceOf[Array[T]]
case _ =>
val a = new Array[T](len)
var i = 0
Expand All @@ -354,7 +365,6 @@ object BasicPicklers extends PicklerHelper with XCompatPicklers {
}
a
}
r
}
}
}
Expand Down
43 changes: 43 additions & 0 deletions boopickle/shared/src/test/scala-2/external/MacroPickleTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,49 @@ object MacroPickleTests extends TestSuite {
val u = Unpickle[MultiT[Int, Double, String]].fromBytes(bb)
assert(x == u)
}
"ArrayDoubleCaseClass" - {
import boopickle.Default._
final case class Probe(a: Array[Double], b: Array[Double])
object Probe {
implicit val pickler: Pickler[Probe] = generatePickler[Probe]
}

"both non-empty" - {
val original = Probe(
a = Array(1.0, 2.0),
b = Array(3.0, 4.0)
)
val bb = Pickle.intoBytes(original)
val u = Unpickle[Probe].fromBytes(bb)

assert(u.a.sameElements(original.a))
assert(u.b.sameElements(original.b))
}

"leading non-empty" - {
val original = Probe(
a = Array(1.0, 2.0),
b = Array.emptyDoubleArray
)
val bb = Pickle.intoBytes(original)
val u = Unpickle[Probe].fromBytes(bb)

assert(u.a.sameElements(original.a))
assert(u.b.sameElements(original.b))
}

"trailing non-empty" - {
val original = Probe(
a = Array.emptyDoubleArray,
b = Array(3.0, 4.0)
)
val bb = Pickle.intoBytes(original)
val u = Unpickle[Probe].fromBytes(bb)

assert(u.a.sameElements(original.a))
assert(u.b.sameElements(original.b))
}
}
}
}
}
43 changes: 43 additions & 0 deletions boopickle/shared/src/test/scala-3/external/MacroPickleTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,49 @@ object MacroPickleTests extends TestSuite {
val u = Unpickle[MultiT[Int, Double, String]].fromBytes(bb)
assert(x == u)
}
"ArrayDoubleCaseClass" - {
import boopickle.Default._
final case class Probe(a: Array[Double], b: Array[Double])
object Probe {
implicit val pickler: Pickler[Probe] = generatePickler[Probe]
}

"both non-empty" - {
val original = Probe(
a = Array(1.0, 2.0),
b = Array(3.0, 4.0)
)
val bb = Pickle.intoBytes(original)
val u = Unpickle[Probe].fromBytes(bb)

assert(u.a.sameElements(original.a))
assert(u.b.sameElements(original.b))
}

"leading non-empty" - {
val original = Probe(
a = Array(1.0, 2.0),
b = Array.emptyDoubleArray
)
val bb = Pickle.intoBytes(original)
val u = Unpickle[Probe].fromBytes(bb)

assert(u.a.sameElements(original.a))
assert(u.b.sameElements(original.b))
}

"trailing non-empty" - {
val original = Probe(
a = Array.emptyDoubleArray,
b = Array(3.0, 4.0)
)
val bb = Pickle.intoBytes(original)
val u = Unpickle[Probe].fromBytes(bb)

assert(u.a.sameElements(original.a))
assert(u.b.sameElements(original.b))
}
}
}
}
}
Loading