summaryrefslogtreecommitdiff
path: root/examples/scala-js/javalib-ex/src/main/scala/java/util/zip/ZipInputStream.scala
blob: 082f6fcc2c293e2500b0621985883128a3dc85e8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package java.util.zip

import java.io._

import scala.scalajs.js
import scala.scalajs.js.typedarray._

class ZipInputStream(in: InputStream) extends InflaterInputStream(in) {

  // Not implemented
  // - All static constant fields (zip internals)
  // - protected def createZipEntry(name: String): ZipEntry

  private[this] val entryIter = {
    import js.Dynamic.{global => g}

    val data = in match {
      case in: ArrayBufferInputStream =>
        // Simulate reading all the data
        while (in.skip(in.available()) > 0) {}
        new Uint8Array(in.buffer, in.offset, in.length)
      case _ =>
        val arr = new js.Array[Int]
        var x = in.read()
        while (x != -1) {
          arr.push(x)
          x = in.read()
        }
        new Uint8Array(arr)
    }

    val zip = js.Dynamic.newInstance(g.JSZip)(data)
    val entries = zip.files.asInstanceOf[js.Dictionary[js.Dynamic]]

    entries.iterator
  }

  private[this] var inner: ArrayBufferInputStream = null

  override def close(): Unit = {
    closeEntry()
    super.close()
  }

  override def available(): Int = {
    if (inner == null || inner.available() <= 0) 0
    else 1
  }

  def closeEntry(): Unit = {
    if (inner != null)
      inner.close()
    inner = null
  }

  def getNextEntry(): ZipEntry = {
    closeEntry()
    if (entryIter.hasNext) {
      val (name, jsEntry) = entryIter.next()
      val res = new ZipEntry(name)
      res.setTime(jsEntry.date.asInstanceOf[js.Date].getTime().toLong)
      res.setComment(jsEntry.comment.asInstanceOf[String])

      inner = new ArrayBufferInputStream(
        jsEntry.asArrayBuffer().asInstanceOf[ArrayBuffer])

      res
    } else null
  }

  override def read(): Int = {
    if (inner == null) -1
    else inner.read()
  }

  override def read(buf: Array[Byte], off: Int, len: Int): Int = {
    if (len == 0) 0
    else if (inner == null) -1
    else inner.read(buf, off, len)
  }

  override def skip(n: Long): Long = {
    if (inner == null) 0
    else inner.skip(n)
  }

}