summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoraleksandar <aleksandar@lampmac14.epfl.ch>2012-01-25 20:17:52 +0100
committeraleksandar <aleksandar@lampmac14.epfl.ch>2012-01-25 20:17:52 +0100
commite234978dfddf5f4871312eb7744ac3b133ad00da (patch)
treeb7412ab8565ae20db1398c1b04297bc1e790fed9 /src
parenta6fcd70b6047ab56cb3415f378ffc8d72a524a8d (diff)
downloadscala-e234978dfddf5f4871312eb7744ac3b133ad00da.tar.gz
scala-e234978dfddf5f4871312eb7744ac3b133ad00da.tar.bz2
scala-e234978dfddf5f4871312eb7744ac3b133ad00da.zip
Refine fix for SI-5374 - make list deserialization backward-compatible.
This is done by structurally serializing list nodes, but prepending a special `ListSerializationStart` symbol ahead of the list. If this symbol is not in the object input stream, the deserialization reverts to the old mode. Note there is not much to be done for list buffers - their serialization was broken before, so legacy serialized list buffers are no longer deserializable. However, their serialVersionUID was changed to reflect this, so deserializing a legacy list buffer should fail fast.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/collection/immutable/List.scala48
-rw-r--r--src/library/scala/collection/mutable/ListBuffer.scala4
2 files changed, 48 insertions, 4 deletions
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index e9ecc75e0f..f789de9fac 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -14,6 +14,7 @@ package immutable
import generic._
import mutable.{Builder, ListBuffer}
import annotation.tailrec
+import java.io._
/** A class for immutable linked lists representing ordered collections
* of elements of type.
@@ -315,8 +316,46 @@ final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extend
override def head : B = hd
override def tail : List[B] = tl
override def isEmpty: Boolean = false
-
-
+
+ private def writeObject(out: ObjectOutputStream) {
+ out.writeObject(ListSerializeStart) // needed to differentiate with the legacy `::` serialization
+ out.writeObject(this.hd)
+ out.writeObject(this.tl)
+ }
+
+ private def readObject(in: ObjectInputStream) {
+ val obj = in.readObject()
+ if (obj == ListSerializeStart) {
+ this.hd = in.readObject().asInstanceOf[B]
+ this.tl = in.readObject().asInstanceOf[List[B]]
+ } else oldReadObject(in, obj)
+ }
+
+ /* The oldReadObject method exists here for compatibility reasons.
+ * :: objects used to be serialized by serializing all the elements to
+ * the output stream directly, but this was broken (see SI-5374).
+ */
+ private def oldReadObject(in: ObjectInputStream, firstObject: AnyRef) {
+ hd = firstObject.asInstanceOf[B]
+ assert(hd != ListSerializeEnd)
+ var current: ::[B] = this
+ while (true) in.readObject match {
+ case ListSerializeEnd =>
+ current.tl = Nil
+ return
+ case a : Any =>
+ val list : ::[B] = new ::(a.asInstanceOf[B], Nil)
+ current.tl = list
+ current = list
+ }
+ }
+
+ private def oldWriteObject(out: ObjectOutputStream) {
+ var xs: List[B] = this
+ while (!xs.isEmpty) { out.writeObject(xs.head); xs = xs.tail }
+ out.writeObject(ListSerializeEnd)
+ }
+
}
/** $factoryInfo
@@ -582,4 +621,9 @@ object List extends SeqFactory[List] {
/** Only used for list serialization */
@SerialVersionUID(0L - 8476791151975527571L)
+private[scala] case object ListSerializeStart
+
+/** Only used for list serialization */
+@SerialVersionUID(0L - 8476791151975527571L)
private[scala] case object ListSerializeEnd
+
diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala
index eb871135df..53c876ec08 100644
--- a/src/library/scala/collection/mutable/ListBuffer.scala
+++ b/src/library/scala/collection/mutable/ListBuffer.scala
@@ -41,7 +41,7 @@ import java.io._
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-@SerialVersionUID(3419063961353022661L)
+@SerialVersionUID(3419063961353022662L)
final class ListBuffer[A]
extends AbstractBuffer[A]
with Buffer[A]
@@ -399,7 +399,7 @@ final class ListBuffer[A]
private def copy() {
var cursor = start
val limit = last0.tail
- clear
+ clear()
while (cursor ne limit) {
this += cursor.head
cursor = cursor.tail