Guest User

Untitled

a guest
Nov 17th, 2017
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.10 KB | None | 0 0
  1. package coms20001
  2.  
  3. import java.io.{BufferedInputStream, BufferedReader, DataInputStream}
  4. import java.nio.charset.StandardCharsets
  5.  
  6. import better.files.File
  7. import coms20001.PGM.{Image, Version}
  8.  
  9. import scala.io.Source
  10. import scala.util.{Failure, Success, Try}
  11.  
  12.  
  13. case class PGM(version: Version,
  14. dimension: (Int, Int),
  15. max: Int,
  16. image: Image) {
  17.  
  18. import better.files.Dsl.SymbolicOperations
  19.  
  20. def write(file: File): Try[File] = Try {
  21. if (!file.isEmpty) throw new IllegalArgumentException(s"File $file not empty")
  22. file.createIfNotExists()
  23. file << version.toString
  24. file << s"${dimension._1} ${dimension._2}"
  25. file << max.toString
  26. file.appendByteArray((for {
  27. r <- image
  28. c <- r
  29. } yield c.toByte).toArray)
  30. file
  31. }
  32.  
  33. override def toString: String = {
  34. val scales = image.map { r =>
  35. r.map { v => v.toInt.toString.padTo(4, ' ') }.mkString
  36. }.mkString("\n")
  37. s"""$version
  38. |${dimension.toString()}
  39. |$max
  40. |$scales""".stripMargin
  41. }
  42. }
  43.  
  44. object PGM {
  45.  
  46. trait Version
  47. case object P5 extends Version
  48.  
  49. type Image = IndexedSeq[IndexedSeq[Char]]
  50.  
  51.  
  52. def read(file: File): Try[PGM] = {
  53.  
  54. val is = new DataInputStream(file.newInputStream)
  55. val reader = Source.fromInputStream(is, StandardCharsets.ISO_8859_1.name).bufferedReader()
  56.  
  57. def fail(reason: String) = Failure(new IllegalArgumentException(reason))
  58.  
  59. val l1 = reader.readLine()
  60. val l2 = reader.readLine()
  61. val l3 = reader.readLine()
  62. if (Seq(l1, l2, l3).contains(null)) throw new IllegalArgumentException(s"EOL for $file")
  63.  
  64. for {
  65. version <- l1.trim match {
  66. case "P5" => Success(P5: Version)
  67. case v@_ => fail(s"bad version $v")
  68. }
  69. dimension@(w, h) <- l2
  70. .trim.split(" ").toList match {
  71. case f :: s :: Nil => for {
  72. w <- Try {f.toInt}
  73. h <- Try {s.toInt}
  74. } yield (w, h)
  75. case v@_ => fail(s"bad dimension $v")
  76. }
  77. max <- Try {l3.trim.toInt}
  78. image <- Try {
  79. val is = new DataInputStream(file.newInputStream)
  80. is.skipBytes(Seq(l1, l2, l3).map {_.length + 1}.sum)
  81. Vector.fill(h) {Vector.fill(w) {is.readUnsignedByte().toChar}}
  82. }
  83. } yield PGM(version, dimension, max, image)
  84. }
  85.  
  86.  
  87. }
Add Comment
Please, Sign In to add comment