All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.velocidi.apso.io.LazySequenceInputStream.scala Maven / Gradle / Ivy

There is a newer version: 0.19.7
Show newest version
package com.velocidi.apso.io

import java.io.InputStream

/** Provides the same functionality as `java.io.SequenceInputStream`, i.e. a `SequenceInputStream` represents the
  * logical concatenation of other input streams. Unlike `SequenceInputStream`, this implementation will open the
  * concatenated input streams lazily (as needed). At any point while reading from the stream, only one underlying
  * `InputStream` should be open.
  * @param streams
  *   A sequence of `InputStream` thunks
  */
class LazySequenceInputStream(private[this] var streams: Seq[() => InputStream]) extends InputStream {
  private[this] var current: InputStream = null

  private[this] def nextStream() = {
    if (current != null) current.close()

    if (streams.nonEmpty) {
      current = streams.head()
      streams = streams.tail

    } else current = null
  }

  nextStream()

  override def available(): Int =
    if (current == null) 0
    else current.available()

  def read(): Int =
    if (current == null) -1
    else {
      val c = current.read()

      if (c == -1) {
        nextStream()
        read()

      } else c
    }

  override def read(b: Array[Byte], off: Int, len: Int): Int =
    if (current == null) -1
    else if (b == null) throw new NullPointerException()
    else if (off < 0 || len < 0 || len > b.length - off) throw new IndexOutOfBoundsException()
    else if (len == 0) 0
    else {
      val n = current.read(b, off, len)

      if (n <= 0) {
        nextStream()
        read(b, off, len)
      } else n
    }

  override def close() = if (current != null) current.close()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy