-
Notifications
You must be signed in to change notification settings - Fork 1
/
zip.clj
47 lines (44 loc) · 1.69 KB
/
zip.clj
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
(ns paprika.zip
(:require [clojure.java.io :as io]
[paprika.io.byte-array :as barray])
(:import [java.util.zip ZipFile ZipInputStream]
[java.io ByteArrayOutputStream]))
(defn read-file [filename]
(let [file (ZipFile. filename)
it (.iterator (.stream file))
next (fn next [] (when (.hasNext it)
(lazy-seq (cons (.next it) (next)))))]
(for [entry (next)
:let [os (ByteArrayOutputStream.)
bytearray (delay
(io/copy (.getInputStream file entry) os)
(.toByteArray os))]]
{:entry entry
:name (.getName entry)
:directory? (.isDirectory entry)
:size (.getSize entry)
:binary bytearray
:contents (delay (String. @bytearray))})))
(defn- read-entry [stream]
(let [ba (byte-array 1024)
out (ByteArrayOutputStream.)]
(loop [read (.read stream ba 0 1024)]
(if (= -1 read)
(.toByteArray out)
(do
(.write out ba 0 read)
(recur (.read stream ba 0 1024)))))))
(defn from-stream [stream]
(let [zip (ZipInputStream. stream)
next-entry (fn aux []
(lazy-seq
(when-let [entry (.getNextEntry zip)]
(let [bin (read-entry zip)]
(cons {:entry entry
:name (.getName entry)
:directory? (.isDirectory entry)
:size (.getSize entry)
:binary bin
:contents (delay (String. bin))}
(aux))))))]
(next-entry)))