diff options
Diffstat (limited to 'examples/scala-js/javalib/src/main/scala/java/io/PrintWriter.scala')
-rw-r--r-- | examples/scala-js/javalib/src/main/scala/java/io/PrintWriter.scala | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/examples/scala-js/javalib/src/main/scala/java/io/PrintWriter.scala b/examples/scala-js/javalib/src/main/scala/java/io/PrintWriter.scala new file mode 100644 index 0000000..4e693e0 --- /dev/null +++ b/examples/scala-js/javalib/src/main/scala/java/io/PrintWriter.scala @@ -0,0 +1,150 @@ +package java.io + +import java.util.Formatter + +class PrintWriter(protected[io] var out: Writer, + autoFlush: Boolean) extends Writer { + + def this(out: Writer) = this(out, false) + + def this(out: OutputStream, autoFlush: Boolean) = + this(new OutputStreamWriter(out), autoFlush) + def this(out: OutputStream) = + this(out, false) + + /* The following constructors, although implemented, will not link, since + * File, FileOutputStream and BufferedOutputStream are not implemented. + * They're here just in case a third-party library on the classpath + * implements those. + */ + def this(file: File) = + this(new BufferedOutputStream(new FileOutputStream(file))) + def this(file: File, csn: String) = + this(new OutputStreamWriter(new BufferedOutputStream( + new FileOutputStream(file)), csn)) + def this(fileName: String) = this(new File(fileName)) + def this(fileName: String, csn: String) = this(new File(fileName), csn) + + private var closed: Boolean = false + private var errorFlag: Boolean = false + + def flush(): Unit = + ensureOpenAndTrapIOExceptions(out.flush()) + + def close(): Unit = trapIOExceptions { + if (!closed) { + flush() + closed = true + out.close() + } + } + + def checkError(): Boolean = { + if (closed) { + /* Just check the error flag. + * Common sense would tell us to look at the underlying writer's + * checkError() result too (like we do in the not closed case below). + * But the JDK does not behave like that. So we don't either. + */ + errorFlag + } else { + flush() + /* If the underlying writer is also a PrintWriter, we also check its + * checkError() result. This is not clearly specified by the JavaDoc, + * but, experimentally, the JDK seems to behave that way. + */ + errorFlag || (out match { + case out: PrintWriter => out.checkError() + case _ => false + }) + } + } + + protected[io] def setError(): Unit = errorFlag = true + protected[io] def clearError(): Unit = errorFlag = false + + override def write(c: Int): Unit = + ensureOpenAndTrapIOExceptions(out.write(c)) + + override def write(buf: Array[Char], off: Int, len: Int): Unit = + ensureOpenAndTrapIOExceptions(out.write(buf, off, len)) + + override def write(buf: Array[Char]): Unit = + ensureOpenAndTrapIOExceptions(out.write(buf)) + + override def write(s: String, off: Int, len: Int): Unit = + ensureOpenAndTrapIOExceptions(out.write(s, off, len)) + + override def write(s: String): Unit = + ensureOpenAndTrapIOExceptions(out.write(s)) + + def print(b: Boolean): Unit = write(String.valueOf(b)) + def print(c: Char): Unit = write(c) + def print(i: Int): Unit = write(String.valueOf(i)) + def print(l: Long): Unit = write(String.valueOf(l)) + def print(f: Float): Unit = write(String.valueOf(f)) + def print(d: Double): Unit = write(String.valueOf(d)) + def print(s: Array[Char]): Unit = write(s) + def print(s: String): Unit = write(if (s == null) "null" else s) + def print(obj: AnyRef): Unit = write(String.valueOf(obj)) + + def println(): Unit = { + write('\n') // In Scala.js the line separator is always LF + if (autoFlush) + flush() + } + + def println(b: Boolean): Unit = { print(b); println() } + def println(c: Char): Unit = { print(c); println() } + def println(i: Int): Unit = { print(i); println() } + def println(l: Long): Unit = { print(l); println() } + def println(f: Float): Unit = { print(f); println() } + def println(d: Double): Unit = { print(d); println() } + def println(s: Array[Char]): Unit = { print(s); println() } + def println(s: String): Unit = { print(s); println() } + def println(obj: AnyRef): Unit = { print(obj); println() } + + def printf(fmt: String, args: Array[Object]): PrintWriter = + format(fmt, args) + + // Not implemented: + //def printf(l: java.util.Locale, fmt: String, args: Array[Object]): PrintWriter = ??? + + def format(fmt: String, args: Array[Object]): PrintWriter = { + new Formatter(this).format(fmt, args) + if (autoFlush) + flush() + this + } + + // Not implemented: + //def format(l: java.util.Locale, fmt: String, args: Array[Object]): PrintWriter = ??? + + override def append(csq: CharSequence): PrintWriter = { + super.append(csq) + this + } + + override def append(csq: CharSequence, start: Int, end: Int): PrintWriter = { + super.append(csq, start, end) + this + } + + override def append(c: Char): PrintWriter = { + super.append(c) + this + } + + @inline private[this] def trapIOExceptions(body: => Unit): Unit = { + try { + body + } catch { + case _: IOException => setError() + } + } + + @inline private[this] def ensureOpenAndTrapIOExceptions(body: => Unit): Unit = { + if (closed) setError() + else trapIOExceptions(body) + } +} |