diff options
Diffstat (limited to 'examples/scala-js/javalib/src/main/scala/java/io')
20 files changed, 0 insertions, 1397 deletions
diff --git a/examples/scala-js/javalib/src/main/scala/java/io/BufferedReader.scala b/examples/scala-js/javalib/src/main/scala/java/io/BufferedReader.scala deleted file mode 100644 index 0f06523..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/BufferedReader.scala +++ /dev/null @@ -1,145 +0,0 @@ -package java.io - -class BufferedReader(in: Reader, sz: Int) extends Reader { - - def this(in: Reader) = this(in, 4096) - - private[this] var buf = new Array[Char](sz) - - /** Last valid value in the buffer (exclusive) */ - private[this] var end = 0 - - /** Next position to read from buffer */ - private[this] var pos = 0 - - private[this] var closed = false - - private[this] var validMark = false - - override def close(): Unit = { - closed = true - } - - override def mark(readAheadLimit: Int): Unit = { - ensureOpen() - - val srcBuf = buf - if (buf.size < readAheadLimit) - buf = new Array[Char](readAheadLimit) - - // Move data to beginning of buffer - if (pos != 0 || (buf ne srcBuf)) - System.arraycopy(srcBuf, pos, buf, 0, end - pos) - - // Update internal state - end -= pos - pos = 0 - validMark = true - } - - override def markSupported(): Boolean = true - - override def read(): Int = { - ensureOpen() - - if (prepareRead()) { - val res = buf(pos).toInt - pos += 1 - res - } else -1 - } - - override def read(cbuf: Array[Char], off: Int, len: Int): Int = { - ensureOpen() - - if (off < 0 || len < 0 || len > cbuf.length - off) - throw new IndexOutOfBoundsException - - if (len == 0) 0 - else if (prepareRead()) { - val count = Math.min(len, end - pos) - System.arraycopy(this.buf, pos, cbuf, off, count) - pos += count - count - } else -1 - } - - def readLine(): String = { - ensureOpen() - - var res = "" - - while (prepareRead() && buf(pos) != '\n' && buf(pos) != '\r') { - res += buf(pos) - pos += 1 - } - - if (pos >= end) { - // We have reached the end of the stream (prepareRead() returned false) - if (res == "") null - else res - } else { - // Consume terminator - pos += 1 - - // Check whether we have a \r\n. This may overrun the buffer - // and then push a value back which may unnecessarily invalidate - // the mark. This mimics java behavior - if (buf(pos-1) == '\r' && prepareRead() && buf(pos) == '\n') - pos += 1 // consume '\n' - - res - } - } - - override def ready(): Boolean = { - ensureOpen() - pos < end || in.ready() - } - - override def reset(): Unit = { - ensureOpen() - - if (!validMark) throw new IOException("Mark invalid") - pos = 0 - } - - override def skip(n: Long): Long = { - if (n < 0) throw new IllegalArgumentException("n negative") - else if (pos < end) { - val count = Math.min(n, end - pos).toInt - pos += count - count.toLong - } else { - validMark = false - in.skip(n) - } - } - - /** Prepare the buffer for reading. Returns false if EOF */ - private def prepareRead(): Boolean = - pos < end || fillBuffer() - - /** Tries to fill the buffer. Returns false if EOF */ - private def fillBuffer(): Boolean = { - if (validMark && end < buf.length) { - // we may not do a full re-read, since we'll damage the mark. - val read = in.read(buf, end, buf.length - end) - if (read > 0) // protect from adding -1 - end += read - read > 0 - } else { - // Full re-read - validMark = false - end = in.read(buf) - pos = 0 - end > 0 - } - } - - private def ensureOpen(): Unit = { - if (closed) - throw new IOException("Operation on closed stream") - } - -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/ByteArrayInputStream.scala b/examples/scala-js/javalib/src/main/scala/java/io/ByteArrayInputStream.scala deleted file mode 100644 index 697e07b..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/ByteArrayInputStream.scala +++ /dev/null @@ -1,58 +0,0 @@ -package java.io - -class ByteArrayInputStream( - protected val buf: Array[Byte], - offset: Int, length: Int) extends InputStream { - - protected val count: Int = offset + length - protected var mark: Int = offset - protected var pos: Int = offset - - def this(buf: Array[Byte]) = this(buf, 0, buf.length) - - override def read(): Int = { - if (pos >= count) - -1 - else { - val res = buf(pos) & 0xFF // convert to unsigned int - pos += 1 - res - } - } - - override def read(b: Array[Byte], off: Int, reqLen: Int): Int = { - if (off < 0 || reqLen < 0 || reqLen > b.length - off) - throw new IndexOutOfBoundsException - - val len = Math.min(reqLen, count - pos) - - if (reqLen == 0) - 0 // 0 requested, 0 returned - else if (len == 0) - -1 // nothing to read at all - else { - System.arraycopy(buf, pos, b, off, len) - pos += len - len - } - } - - override def skip(n: Long): Long = { - val k = Math.max(0, Math.min(n, count - pos)) - pos += k.toInt - k.toLong - } - - override def available(): Int = count - pos - - override def markSupported(): Boolean = true - - override def mark(readlimit: Int): Unit = - mark = pos - - override def reset(): Unit = - pos = mark - - override def close(): Unit = () - -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/ByteArrayOutputStream.scala b/examples/scala-js/javalib/src/main/scala/java/io/ByteArrayOutputStream.scala deleted file mode 100644 index 916002d..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/ByteArrayOutputStream.scala +++ /dev/null @@ -1,62 +0,0 @@ -package java.io - -import scala.scalajs.js - -import scala.annotation.tailrec - -class ByteArrayOutputStream(initBufSize: Int) extends OutputStream { - - protected var buf: Array[Byte] = new Array(initBufSize) - protected var count: Int = 0 - - def this() = this(32) - - override def write(b: Int): Unit = { - if (count >= buf.length) - growBuf(1) - - buf(count) = b.toByte - count += 1 - } - - override def write(b: Array[Byte], off: Int, len: Int): Unit = { - if (off < 0 || len < 0 || len > b.length - off) - throw new IndexOutOfBoundsException() - - if (count + len > buf.length) - growBuf(len) - - System.arraycopy(b, off, buf, count, len) - count += len - } - - def writeTo(out: OutputStream): Unit = - out.write(buf, 0, count) - - def reset(): Unit = - count = 0 - - def toByteArray(): Array[Byte] = { - val res = new Array[Byte](count) - System.arraycopy(buf, 0, res, 0, count) - res - } - - def size(): Int = count - - override def toString(): String = - new String(buf, 0, count) - - def toString(charsetName: String): String = - new String(buf, 0, count, charsetName) - - override def close(): Unit = () - - private def growBuf(minIncrement: Int): Unit = { - val newSize = Math.max(count + minIncrement, buf.length * 2) - val newBuf = new Array[Byte](newSize) - System.arraycopy(buf, 0, newBuf, 0, count) - buf = newBuf - } - -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/Closeable.scala b/examples/scala-js/javalib/src/main/scala/java/io/Closeable.scala deleted file mode 100644 index e572390..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/Closeable.scala +++ /dev/null @@ -1,6 +0,0 @@ -package java.io - -/** Note that Closeable doesn't extend AutoCloseable for Java6 compat */ -trait Closeable { - def close(): Unit -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/DataInput.scala b/examples/scala-js/javalib/src/main/scala/java/io/DataInput.scala deleted file mode 100644 index 37913b4..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/DataInput.scala +++ /dev/null @@ -1,19 +0,0 @@ -package java.io - -trait DataInput { - def readBoolean(): Boolean - def readByte(): Byte - def readChar(): Char - def readDouble(): Double - def readFloat(): Float - def readFully(b: Array[Byte]): Unit - def readFully(b: Array[Byte], off: Int, len: Int): Unit - def readInt(): Int - def readLine(): String - def readLong(): Long - def readShort(): Short - def readUnsignedByte(): Int - def readUnsignedShort(): Int - def readUTF(): String - def skipBytes(n: Int): Int -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/FilterInputStream.scala b/examples/scala-js/javalib/src/main/scala/java/io/FilterInputStream.scala deleted file mode 100644 index a85b9f6..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/FilterInputStream.scala +++ /dev/null @@ -1,24 +0,0 @@ -package java.io - -class FilterInputStream protected ( - protected val in: InputStream) extends InputStream { - - override def read(): Int = - in.read() - - override def read(b: Array[Byte]): Int = - read(b, 0, b.length) // this is spec! must not do in.read(b) - - override def read(b: Array[Byte], off: Int, len: Int): Int = - in.read(b, off, len) - - override def skip(n: Long): Long = in.skip(n) - - override def available(): Int = in.available() - - override def close(): Unit = in.close() - - override def mark(readlimit: Int): Unit = in.mark(readlimit) - override def markSupported(): Boolean = in.markSupported() - override def reset(): Unit = in.reset() -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/FilterOutputStream.scala b/examples/scala-js/javalib/src/main/scala/java/io/FilterOutputStream.scala deleted file mode 100644 index 299b7b6..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/FilterOutputStream.scala +++ /dev/null @@ -1,16 +0,0 @@ -package java.io - -class FilterOutputStream(protected val out: OutputStream) extends OutputStream { - def write(b: Int): Unit = - out.write(b) - - override def write(b: Array[Byte]): Unit = - write(b, 0, b.length) // this is spec! it must not call out.write(b) - - override def write(b: Array[Byte], off: Int, len: Int): Unit = - super.write(b, off, len) // calls this.write(Int) repeatedly - - override def flush(): Unit = out.flush() - - override def close(): Unit = out.close() -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/Flushable.scala b/examples/scala-js/javalib/src/main/scala/java/io/Flushable.scala deleted file mode 100644 index 2879ad2..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/Flushable.scala +++ /dev/null @@ -1,5 +0,0 @@ -package java.io - -trait Flushable { - def flush(): Unit -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/InputStream.scala b/examples/scala-js/javalib/src/main/scala/java/io/InputStream.scala deleted file mode 100644 index 412d84b..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/InputStream.scala +++ /dev/null @@ -1,53 +0,0 @@ -package java.io - -abstract class InputStream extends Closeable { - def read(): Int - - def read(b: Array[Byte]): Int = read(b, 0, b.length) - - def read(b: Array[Byte], off: Int, len: Int): Int = { - if (off < 0 || len < 0 || len > b.length - off) - throw new IndexOutOfBoundsException - - if (len == 0) 0 - else { - var bytesWritten = 0 - var next = 0 - - while (bytesWritten < len && next != -1) { - next = - if (bytesWritten == 0) read() - else { - try read() - catch { case _: IOException => -1 } - } - if (next != -1) { - b(off + bytesWritten) = next.toByte - bytesWritten += 1 - } - } - - if (bytesWritten <= 0) -1 - else bytesWritten - } - } - - def skip(n: Long): Long = { - var skipped = 0 - while (skipped < n && read() != -1) - skipped += 1 - skipped - } - - def available(): Int = 0 - - def close(): Unit = () - - def mark(readlimit: Int): Unit = () - - def reset(): Unit = - throw new IOException("Reset not supported") - - def markSupported(): Boolean = false - -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/InputStreamReader.scala b/examples/scala-js/javalib/src/main/scala/java/io/InputStreamReader.scala deleted file mode 100644 index 1ef957c..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/InputStreamReader.scala +++ /dev/null @@ -1,216 +0,0 @@ -package java.io - -import scala.annotation.tailrec - -import java.nio._ -import java.nio.charset._ - -class InputStreamReader(private[this] var in: InputStream, - private[this] var decoder: CharsetDecoder) extends Reader { - - private[this] var closed: Boolean = false - - /** Buffer in which to read bytes from the underlying input stream. - * - * Class invariant: contains bytes already read from `in` but not yet - * decoded. - */ - private[this] var inBuf: ByteBuffer = ByteBuffer.allocate(4096) - inBuf.limit(0) - - /** Tells whether the end of the underlying input stream has been reached. - * Class invariant: if true, then `in.read()` has returned -1. - */ - private[this] var endOfInput: Boolean = false - - /** Buffer in which to decode bytes into chars. - * Usually, it is not used, because we try to decode directly to the - * destination array. So as long as we do not really need one, we share - * an empty buffer. - * - * Class invariant: contains chars already decoded but not yet *read* by - * the user of this instance. - */ - private[this] var outBuf: CharBuffer = InputStreamReader.CommonEmptyCharBuffer - - def this(in: InputStream, charset: Charset) = - this(in, - charset.newDecoder - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE)) - - def this(in: InputStream) = - this(in, Charset.defaultCharset) - - def this(in: InputStream, charsetName: String) = - this(in, Charset.forName(charsetName)) - - def close(): Unit = { - closed = true - in = null - decoder = null - inBuf = null - outBuf = null - } - - def getEncoding(): String = - if (closed) null else decoder.charset.name - - override def read(): Int = { - ensureOpen() - - if (outBuf.hasRemaining) outBuf.get() - else super.read() - } - - def read(cbuf: Array[Char], off: Int, len: Int): Int = { - ensureOpen() - - if (off < 0 || len < 0 || len > cbuf.length - off) - throw new IndexOutOfBoundsException - - if (len == 0) 0 - else if (outBuf.hasRemaining) { - // Reuse chars decoded last time - val available = Math.min(outBuf.remaining, len) - outBuf.get(cbuf, off, available) - available - } else { - // Try and decode directly into the destination array - val directOut = CharBuffer.wrap(cbuf, off, len) - val result = readImpl(directOut) - if (result != InputStreamReader.Overflow) { - result - } else { - /* There's not enough space in the destination array to receive even - * a tiny bit of output from the decoder. We need to decode to the - * outBuf instead. - * This happens typically when the next code point to decode is a - * supplementary character, and the given `len` is 1. - */ - readMoreThroughOutBuf(cbuf, off, len) - } - } - } - - // In a separate method because this is (hopefully) not a common case - private def readMoreThroughOutBuf(cbuf: Array[Char], off: Int, len: Int): Int = { - // Return outBuf to its full capacity - outBuf.limit(outBuf.capacity) - outBuf.position(0) - - @tailrec // but not inline, this is not a common path - def loopWithOutBuf(desiredOutBufSize: Int): Int = { - if (outBuf.capacity < desiredOutBufSize) - outBuf = CharBuffer.allocate(desiredOutBufSize) - val charsRead = readImpl(outBuf) - if (charsRead == InputStreamReader.Overflow) - loopWithOutBuf(desiredOutBufSize*2) - else - charsRead - } - - val charsRead = loopWithOutBuf(2*len) - assert(charsRead != 0) // can be -1, though - outBuf.flip() - - if (charsRead == -1) -1 - else { - val available = Math.min(charsRead, len) - outBuf.get(cbuf, off, available) - available - } - } - - @tailrec - private def readImpl(out: CharBuffer): Int = { - val initPos = out.position - val result = decoder.decode(inBuf, out, endOfInput) - - if (out.position != initPos) { - /* Good, we made progress, so we can return. - * Note that the `result` does not matter. Whether it's an underflow, - * an overflow, or even an error, if we read *something*, we can return - * that. - * The next invocation of read() will cause a new invocation of decode(), - * which will necessarily return the same result (but without advancing - * at all), which will cause one of the following cases to be handled. - */ - out.position - initPos - } else if (result.isUnderflow) { - if (endOfInput) { - assert(!inBuf.hasRemaining, - "CharsetDecoder.decode() should not have returned UNDERFLOW when "+ - "both endOfInput and inBuf.hasRemaining are true. It should have "+ - "returned a MalformedInput error instead.") - // Flush - if (decoder.flush(out).isOverflow) - InputStreamReader.Overflow - else { - // Done - if (out.position == initPos) -1 - else out.position - initPos - } - } else { - // We need to read more from the underlying input stream - if (inBuf.limit == inBuf.capacity) { - inBuf.compact() - if (!inBuf.hasRemaining) { - throw new AssertionError( - "Scala.js implementation restriction: " + - inBuf.capacity + " bytes do not seem to be enough for " + - getEncoding + " to decode a single code point. " + - "Please report this as a bug.") - } - inBuf.limit(inBuf.position) - inBuf.position(0) - } - - /* Note that this stores the new data after the limit of the buffer. - * Further, note that we may read more bytes than strictly necessary, - * according to the specification of InputStreamReader. - */ - val bytesRead = - in.read(inBuf.array, inBuf.limit, inBuf.capacity - inBuf.limit) - - if (bytesRead == -1) - endOfInput = true - else - inBuf.limit(inBuf.limit + bytesRead) - - readImpl(out) - } - } else if (result.isOverflow) { - InputStreamReader.Overflow - } else { - result.throwException() - throw new AssertionError("should not get here") - } - } - - /* In theory, `in.available() > 0` is incorrect. We should return true only - * if there are enough bytes available to read at least one code point. - * However, this is how the JDK behaves, and even the JavaDoc suggests this - * is the expected behavior. - */ - override def ready(): Boolean = - outBuf.hasRemaining || in.available() > 0 - - private def ensureOpen(): Unit = { - if (closed) - throw new IOException("Stream closed") - } - -} - -object InputStreamReader { - private final val Overflow = -2 - - /** Empty CharBuffer shared by all InputStreamReaders as long as they do - * not really need one. - * Since we do not use `mark()`, it is fine to share them, because `mark()` - * is the only piece of mutable state for an empty buffer. Everything else - * is effectively immutable (e.g., position and limit must always be 0). - */ - private val CommonEmptyCharBuffer = CharBuffer.allocate(0) -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/OutputStream.scala b/examples/scala-js/javalib/src/main/scala/java/io/OutputStream.scala deleted file mode 100644 index 729e69b..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/OutputStream.scala +++ /dev/null @@ -1,25 +0,0 @@ -package java.io - -abstract class OutputStream extends Object with Closeable with Flushable { - def write(b: Int): Unit - - def write(b: Array[Byte]): Unit = - write(b, 0, b.length) - - def write(b: Array[Byte], off: Int, len: Int): Unit = { - if (off < 0 || len < 0 || len > b.length - off) - throw new IndexOutOfBoundsException() - - var n = off - val stop = off + len - while (n < stop) { - write(b(n)) - n += 1 - } - } - - def flush(): Unit = () - - def close(): Unit = () - -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/OutputStreamWriter.scala b/examples/scala-js/javalib/src/main/scala/java/io/OutputStreamWriter.scala deleted file mode 100644 index 18c1c57..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/OutputStreamWriter.scala +++ /dev/null @@ -1,160 +0,0 @@ -package java.io - -import scala.annotation.tailrec - -import java.nio._ -import java.nio.charset._ - -class OutputStreamWriter(private[this] var out: OutputStream, - private[this] var enc: CharsetEncoder) extends Writer { - - private[this] var closed: Boolean = false - - /** Incoming buffer: pending Chars that have been written to this instance - * of OutputStreamWriter, but not yet encoded. - * Normally, this should always be at most 1 Char, if it is a high surrogate - * which ended up alone at the end of the input of a write(). - */ - private[this] var inBuf: String = "" - - /** Outgoing buffer: Bytes that have been decoded (from `inBuf`), but not - * yet written to the underlying output stream. - * The valid bytes are between 0 and outBuf.position. - */ - private[this] var outBuf: ByteBuffer = ByteBuffer.allocate(4096) - - def this(out: OutputStream, cs: Charset) = - this(out, - cs.newEncoder - .onMalformedInput(CodingErrorAction.REPLACE) - .onUnmappableCharacter(CodingErrorAction.REPLACE)) - - def this(out: OutputStream) = - this(out, Charset.defaultCharset) - - def this(out: OutputStream, charsetName: String) = - this(out, Charset.forName(charsetName)) - - def getEncoding(): String = - if (closed) null else enc.charset.name - - override def write(c: Int): Unit = - write(c.toChar.toString, 0, 1) - - override def write(cbuf: Array[Char], off: Int, len: Int): Unit = - writeImpl(CharBuffer.wrap(cbuf, off, len)) - - override def write(str: String, off: Int, len: Int): Unit = - writeImpl(CharBuffer.wrap(str, off, len)) - - private def writeImpl(cbuf: CharBuffer): Unit = { - ensureOpen() - - val cbuf1 = if (inBuf != "") { - val fullInput = CharBuffer.wrap(inBuf + cbuf.toString) - inBuf = "" - fullInput - } else cbuf - - @inline - @tailrec - def loopEncode(): Unit = { - val result = enc.encode(cbuf1, outBuf, false) - if (result.isUnderflow) () - else if (result.isOverflow) { - makeRoomInOutBuf() - loopEncode() - } else { - result.throwException() - throw new AssertionError("should not get here") - } - } - - loopEncode() - if (cbuf1.hasRemaining) - inBuf = cbuf1.toString - } - - override def flush(): Unit = { - ensureOpen() - flushBuffer() - out.flush() - } - - override def close(): Unit = if (!closed) { - // Finish up the input - @inline - @tailrec - def loopEncode(): Unit = { - val cbuf = CharBuffer.wrap(inBuf) - val result = enc.encode(cbuf, outBuf, true) - if (result.isUnderflow) { - assert(!cbuf.hasRemaining, - "CharsetEncoder.encode() should not have returned UNDERFLOW when "+ - "both endOfInput and inBuf.hasRemaining are true. It should have "+ - "returned a MalformedInput error instead.") - } else if (result.isOverflow) { - makeRoomInOutBuf() - loopEncode() - } else { - result.throwException() - throw new AssertionError("should not get here") - } - } - - @inline - @tailrec - def loopFlush(): Unit = { - if (enc.flush(outBuf).isOverflow) { - makeRoomInOutBuf() - loopFlush() - } - } - - loopEncode() - loopFlush() - - // Flush before closing - flush() - - // Close the underlying stream - out.close() - - // Clean up all the resources - closed = true - out = null - enc = null - inBuf = null - outBuf = null - } - - private def ensureOpen(): Unit = { - if (closed) - throw new IOException("Closed writer.") - } - - private def makeRoomInOutBuf(): Unit = { - if (outBuf.position != 0) { - flushBuffer() - } else { - // Very unlikely (outBuf.capacity is not enough to encode a single code point) - outBuf.flip() - val newBuf = ByteBuffer.allocate(outBuf.capacity * 2) - newBuf.put(outBuf) - outBuf = newBuf - } - } - - /** Flushes the internal buffer of this writer, but not the underlying - * output stream. - */ - private[io] def flushBuffer(): Unit = { - ensureOpen() - - // Don't use outBuf.flip() first, in case out.write() throws - // Hence, use 0 instead of position, and position instead of limit - out.write(outBuf.array, outBuf.arrayOffset, outBuf.position) - outBuf.clear() - } - -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/PrintStream.scala b/examples/scala-js/javalib/src/main/scala/java/io/PrintStream.scala deleted file mode 100644 index 68fa041..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/PrintStream.scala +++ /dev/null @@ -1,218 +0,0 @@ -package java.io - -import java.nio.charset.Charset -import java.util.Formatter - -class PrintStream private (_out: OutputStream, autoFlush: Boolean, - charset: Charset) - extends FilterOutputStream(_out) with Appendable with Closeable { - - /* The way we handle charsets here is a bit tricky, because we want to - * minimize the area of reachability for normal programs. - * - * First, if nobody uses the constructor taking an explicit encoding, we - * don't want to reach Charset.forName(), which pulls in all of the - * implemented charsets. - * - * Second, most programs will reach PrintStream only because of - * java.lang.System.{out,err}, which are subclasses of PrintStream that do - * not actually need to encode anything: they override all of PrintStream's - * methods to bypass the encoding altogether, and hence don't even need - * the default charset. - * - * This is why we have: - * * A private constructor taking the Charset directly, instead of its name. - * * Which is allowed to be `null`, which stands for the default charset. - * * The default charset is only loaded lazily in the initializer of the - * encoder field. - */ - - def this(out: OutputStream) = - this(out, false, null: Charset) - - def this(out: OutputStream, autoFlush: Boolean) = - this(out, autoFlush, null: Charset) - - def this(out: OutputStream, autoFlush: Boolean, encoding: String) = - this(out, autoFlush, Charset.forName(encoding)) - - /* 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 BufferedOutputStream(new FileOutputStream(file)), false, csn) - def this(fileName: String) = - this(new File(fileName)) - def this(fileName: String, csn: String) = - this(new File(fileName), csn) - - private lazy val encoder = { - val c = - if (charset == null) Charset.defaultCharset - else charset - /* We pass `this` as the output stream for the encoding writer so that - * we can apply auto-flushing. Note that this will flush() more often - * than required by the spec. It appears to be consistent with how the - * JDK behaves. - */ - new OutputStreamWriter(this, c) - } - - private var closing: Boolean = false - private var closed: Boolean = false - private var errorFlag: Boolean = false - - override def flush(): Unit = - ensureOpenAndTrapIOExceptions(out.flush()) - - override def close(): Unit = trapIOExceptions { - if (!closing) { - closing = true - encoder.close() - 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 PrintStream, 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: PrintStream => out.checkError() - case _ => false - }) - } - } - - protected[io] def setError(): Unit = errorFlag = true - protected[io] def clearError(): Unit = errorFlag = false - - /* Note that calling directly the write() methods will happily bypass the - * potential lone high surrogate that is buffered in the underlying - * OutputStreamWriter. This means that the following sequence of operations: - * - * ps.print('\ud83d') // high surrogate of PILE OF POO - * ps.write('a') - * ps.print('\udca9') // low surrogate of PILE OF POO - * - * will result in the following bytes being emitted to the underlying stream: - * - * a\ud83d\udca9 - * - * i.e., first the 'a', then the PILE OF POO. - * - * This is consistent with the behavior of the JDK. - */ - - override def write(b: Int): Unit = { - ensureOpenAndTrapIOExceptions { - out.write(b) - if (autoFlush && b == '\n') - flush() - } - } - - override def write(buf: Array[Byte], off: Int, len: Int): Unit = { - ensureOpenAndTrapIOExceptions { - out.write(buf, off, len) - if (autoFlush) - flush() - } - } - - def print(b: Boolean): Unit = printString(String.valueOf(b)) - def print(c: Char): Unit = printString(String.valueOf(c)) - def print(i: Int): Unit = printString(String.valueOf(i)) - def print(l: Long): Unit = printString(String.valueOf(l)) - def print(f: Float): Unit = printString(String.valueOf(f)) - def print(d: Double): Unit = printString(String.valueOf(d)) - def print(s: String): Unit = printString(if (s == null) "null" else s) - def print(obj: AnyRef): Unit = printString(String.valueOf(obj)) - - private def printString(s: String): Unit = ensureOpenAndTrapIOExceptions { - encoder.write(s) - encoder.flushBuffer() - } - - def print(s: Array[Char]): Unit = ensureOpenAndTrapIOExceptions { - encoder.write(s) - encoder.flushBuffer() - } - - def println(): Unit = ensureOpenAndTrapIOExceptions { - encoder.write('\n') // In Scala.js the line separator is always LF - encoder.flushBuffer() - 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]): PrintStream = - format(fmt, args) - - // Not implemented: - //def printf(l: java.util.Locale, fmt: String, args: Array[Object]): PrintStream = ??? - - def format(fmt: String, args: Array[Object]): PrintStream = { - new Formatter(this).format(fmt, args) - this - } - - // Not implemented: - //def format(l: java.util.Locale, fmt: String, args: Array[Object]): PrintStream = ??? - - def append(csq: CharSequence): PrintStream = { - print(if (csq == null) "null" else csq.toString) - this - } - - def append(csq: CharSequence, start: Int, end: Int): PrintStream = { - val csq1 = if (csq == null) "null" else csq - print(csq1.subSequence(start, end).toString) - this - } - - def append(c: Char): PrintStream = { - print(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) - } - -} 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 deleted file mode 100644 index 4e693e0..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/PrintWriter.scala +++ /dev/null @@ -1,150 +0,0 @@ -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) - } -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/Reader.scala b/examples/scala-js/javalib/src/main/scala/java/io/Reader.scala deleted file mode 100644 index 97be140..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/Reader.scala +++ /dev/null @@ -1,60 +0,0 @@ -package java.io - -import java.nio.CharBuffer - -abstract class Reader private[this] (_lock: Option[Object]) - extends Readable with Closeable { - - protected val lock = _lock.getOrElse(this) - - protected def this(lock: Object) = this(Some(lock)) - protected def this() = this(None) - - def read(target: CharBuffer): Int = { - if (!target.hasRemaining) 0 - else if (target.hasArray) { - val charsRead = read(target.array, - target.position + target.arrayOffset, target.remaining) - if (charsRead != -1) - target.position(target.position + charsRead) - charsRead - } else { - val buf = new Array[Char](target.remaining) - val charsRead = read(buf) - if (charsRead != -1) - target.put(buf, 0, charsRead) - charsRead - } - } - - def read(): Int = { - val buf = new Array[Char](1) - if (read(buf) == -1) -1 - else buf(0).toInt - } - - def read(cbuf: Array[Char]): Int = - read(cbuf, 0, cbuf.length) - - def read(cbuf: Array[Char], off: Int, len: Int): Int - - def skip(n: Long): Long = { - if (n < 0) - throw new IllegalArgumentException("Cannot skip negative amount") - else if (read() == -1) 0 - else 1 - } - - def ready(): Boolean = false - - def markSupported(): Boolean = false - - def mark(readAheadLimit: Int): Unit = - throw new IOException("Mark not supported") - - def reset(): Unit = - throw new IOException("Reset not supported") - - def close(): Unit - -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/Serializable.scala b/examples/scala-js/javalib/src/main/scala/java/io/Serializable.scala deleted file mode 100644 index 01dd228..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/Serializable.scala +++ /dev/null @@ -1,3 +0,0 @@ -package java.io - -trait Serializable diff --git a/examples/scala-js/javalib/src/main/scala/java/io/StringReader.scala b/examples/scala-js/javalib/src/main/scala/java/io/StringReader.scala deleted file mode 100644 index 2ca8f90..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/StringReader.scala +++ /dev/null @@ -1,69 +0,0 @@ -package java.io - -class StringReader(s: String) extends Reader { - - private[this] var closed = false - private[this] var pos = 0 - private[this] var mark = 0 - - override def close(): Unit = { - closed = true - } - - override def mark(readAheadLimit: Int): Unit = { - ensureOpen() - - mark = pos - } - - override def markSupported(): Boolean = true - - override def read(): Int = { - ensureOpen() - - if (pos < s.length) { - val res = s.charAt(pos).toInt - pos += 1 - res - } else -1 - } - - override def read(cbuf: Array[Char], off: Int, len: Int): Int = { - ensureOpen() - - if (off < 0 || len < 0 || len > cbuf.length - off) - throw new IndexOutOfBoundsException - - if (len == 0) 0 - else { - val count = Math.min(len, s.length - pos) - var i = 0 - while (i < count) { - cbuf(off + i) = s.charAt(pos + i) - i += 1 - } - pos += count - count - } - } - - override def ready(): Boolean = pos < s.length - - override def reset(): Unit = { - ensureOpen() - pos = mark - } - - override def skip(ns: Long): Long = { - // Apparently, StringReader.skip allows negative skips - val count = Math.max(Math.min(ns, s.length - pos).toInt, -pos) - pos += count - count.toLong - } - - private def ensureOpen(): Unit = { - if (closed) - throw new IOException("Operation on closed stream") - } - -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/StringWriter.scala b/examples/scala-js/javalib/src/main/scala/java/io/StringWriter.scala deleted file mode 100644 index 13eca00..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/StringWriter.scala +++ /dev/null @@ -1,44 +0,0 @@ -package java.io - -class StringWriter extends Writer { - - private[this] val buf = new StringBuffer - - def this(initialSize: Int) = this() - - override def write(c: Int): Unit = - buf.append(c.toChar) - - def write(cbuf: Array[Char], off: Int, len: Int): Unit = - buf.append(cbuf, off, len) - - override def write(str: String): Unit = - buf.append(str) - - override def write(str: String, off: Int, len: Int): Unit = - buf.append(str, off, off + len) // Third param is 'end', not 'len' - - override def append(csq: CharSequence): StringWriter = { - buf.append(csq) - this - } - - override def append(csq: CharSequence, start: Int, end: Int): StringWriter = { - buf.append(csq, start, end) - this - } - - override def append(c: Char): StringWriter = { - buf.append(c) - this - } - - override def toString(): String = buf.toString - - def getBuffer(): StringBuffer = buf - - def flush(): Unit = () - - def close(): Unit = () - -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/Throwables.scala b/examples/scala-js/javalib/src/main/scala/java/io/Throwables.scala deleted file mode 100644 index c312c4c..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/Throwables.scala +++ /dev/null @@ -1,19 +0,0 @@ -package java.io - -class IOException(s: String, e: Throwable) extends Exception(s, e) { - def this(e: Throwable) = this(null, e) - def this(s: String) = this(s, null) - def this() = this(null, null) -} - -class EOFException(s: String) extends IOException(s) { - def this() = this(null) -} - -class UTFDataFormatException(s: String) extends IOException(s) { - def this() = this(null) -} - -class UnsupportedEncodingException(s: String) extends IOException(s) { - def this() = this(null) -} diff --git a/examples/scala-js/javalib/src/main/scala/java/io/Writer.scala b/examples/scala-js/javalib/src/main/scala/java/io/Writer.scala deleted file mode 100644 index d63b477..0000000 --- a/examples/scala-js/javalib/src/main/scala/java/io/Writer.scala +++ /dev/null @@ -1,45 +0,0 @@ -package java.io - -abstract class Writer private[this] (_lock: Option[Object]) extends - Appendable with Closeable with Flushable { - - protected val lock = _lock.getOrElse(this) - - protected def this(lock: Object) = this(Some(lock)) - protected def this() = this(None) - - def write(c: Int): Unit = - write(Array(c.toChar)) - - def write(cbuf: Array[Char]): Unit = - write(cbuf, 0, cbuf.length) - - def write(cbuf: Array[Char], off: Int, len: Int): Unit - - def write(str: String): Unit = - write(str.toCharArray) - - def write(str: String, off: Int, len: Int): Unit = - write(str.toCharArray, off, len) - - def append(csq: CharSequence): Writer = { - write(if (csq == null) "null" else csq.toString) - this - } - - def append(csq: CharSequence, start: Int, end: Int): Writer = { - val csq1 = if (csq == null) "null" else csq - write(csq1.subSequence(start, end).toString) - this - } - - def append(c: Char): Writer = { - write(c.toInt) - this - } - - def flush(): Unit - - def close(): Unit - -} |