Advertisement
Guest User

Untitled

a guest
Nov 29th, 2015
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.28 KB | None | 0 0
  1. object lzw {
  2.  
  3. trait Appendable[T] {
  4. def append(value: T)
  5. }
  6.  
  7. import scala.collection.generic._
  8. case class GrowingAppendable[T](growable: Growable[T]) extends Appendable[T] {
  9. def append(value: T) {
  10. growable += value
  11. }
  12. }
  13.  
  14. trait Node {
  15. def encode(b: Byte, out: Appendable[Int]): Node
  16. def decode(i: Int, out: Appendable[Byte]): Node
  17. def terminate(out: Appendable[Int]): Unit
  18. }
  19.  
  20. class ValueNode(value: Int, rootNode: RootNode, val path: Array[Byte]) extends Node {
  21.  
  22. private val nodes = new Array[Node](255)
  23.  
  24. def encode(b: Byte, out: Appendable[Int]): Node = Option(nodes(0xff & b)).getOrElse {
  25. out.append(value)
  26. rootNode.createNode(path :+ b) match {
  27. case Some(node) =>
  28. nodes(0xff & b) = node
  29. rootNode.encode(b, out)
  30. case None =>
  31. rootNode.encode(b, out)
  32. }
  33. }
  34.  
  35. def decode(i: Int, out: Appendable[Byte]): Node = {
  36. val node = rootNode.nodeByValue(i).get
  37. val firstByte = node.path.head
  38. for (b <- node.path) out.append(b)
  39. if (nodes(0xff & firstByte) == null) {
  40. val next = rootNode.createNode(path :+ firstByte).get
  41. nodes(0xff & firstByte) = next
  42. }
  43. node
  44. }
  45.  
  46. def terminate(out: Appendable[Int]) {
  47. out.append(value)
  48. }
  49.  
  50.  
  51. override def toString = "ValueNode(" + value + ")"
  52. }
  53.  
  54. class RootNode(limit: Int = 512) extends Node {
  55.  
  56. private var index = 256
  57.  
  58. private val initial = Array.tabulate[ValueNode](256)(b => new ValueNode(b, this, Array[Byte](b.asInstanceOf[Byte])))
  59.  
  60. private val createdNodes = new Array[ValueNode](limit - 256)
  61.  
  62. def encode(b: Byte, out: Appendable[Int]): Node = initial(0xff & b)
  63.  
  64. def decode(i: Int, out: Appendable[Byte]): Node = {
  65. val node = nodeByValue(i).get
  66. for (b <- node.path) out.append(b)
  67. node
  68. }
  69.  
  70. def createNode(path: Array[Byte]): Option[Node] = {
  71. if (index <= limit) {
  72. val node = new ValueNode(index, this, path)
  73. createdNodes(index - 256) = node
  74. index += 1
  75. Some(node)
  76. } else {
  77. // In this particular implementation, there is no reset (yet)
  78. None
  79. }
  80. }
  81.  
  82. def nodeByValue(value: Int): Option[ValueNode] =
  83. // This method should use asserts rather than options
  84. if (value < 256) Some(initial(value))
  85. else if (value > index) None
  86. else Some(createdNodes(value - 256))
  87.  
  88. def terminate(out: Appendable[Int]) { }
  89.  
  90. override def toString = "RootNode"
  91. }
  92.  
  93. implicit def growableToAppendable[T](growable: Growable[T]) = new GrowingAppendable(growable)
  94.  
  95. implicit def stringToByteIterable(str: String) = str.getBytes.toIterable
  96.  
  97. def encode[F <% Iterable[Byte], T <% Appendable[Int]](in: F, out: T) =
  98. in.foldLeft(new RootNode().asInstanceOf[Node])({ (node, b) => node.encode(b, out) }).terminate(out)
  99.  
  100. def decode[F <% Iterable[Int], T <% Appendable[Byte]](in: F, out: T) =
  101. in.foldLeft(new RootNode().asInstanceOf[Node])({ (node, i) => node.decode(i, out) })
  102.  
  103. def encode[F <% Iterable[Byte]](in: F): Seq[Int] = {
  104. val buffer = new scala.collection.mutable.ArrayBuffer[Int]
  105. encode(in, buffer)
  106. buffer
  107. }
  108.  
  109. def decode[F <% Iterable[Int]](in: F): Seq[Byte] = {
  110. val buffer = new scala.collection.mutable.ArrayBuffer[Byte]
  111. decode(in, buffer)
  112. buffer
  113. }
  114.  
  115. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement