aboutsummaryrefslogtreecommitdiff
path: root/lux-bootstrapper/src/lux/lib/loader.clj
blob: 97e6ee684d4ecb1def826fa85ed192be9ad0366c (plain)
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
(ns lux.lib.loader
  (:refer-clojure :exclude [load])
  (:require (lux [base :as & :refer [|let |do return return* |case]]))
  (:import (java.io InputStream
                    File
                    FileInputStream
                    ByteArrayInputStream
                    ByteArrayOutputStream)
           java.util.jar.JarInputStream))

;; [Utils]
(let [init-capacity (* 100 1024)
      buffer-size 1024]
  (defn ^:private ^"[B" read-stream [^InputStream is]
    (let [buffer (byte-array buffer-size)]
      (with-open [os (new ByteArrayOutputStream init-capacity)]
        (loop [bytes-read (.read is buffer 0 buffer-size)]
          (when (not= -1 bytes-read)
            (do (.write os buffer 0 bytes-read)
              (recur (.read is buffer 0 buffer-size)))))
        (.toByteArray os)))))

(defn ^:private unpackage [^File lib-file]
  (let [is (->> lib-file
                (new FileInputStream)
                (new JarInputStream))]
    (loop [lib-data {}
           entry (.getNextJarEntry is)]
      (if entry
        (if (.endsWith (.getName entry) ".lux")
          (recur (assoc lib-data (.getName entry) (new String (read-stream is)))
                 (.getNextJarEntry is))
          (recur lib-data
                 (.getNextJarEntry is)))
        lib-data))))

;; [Exports]
(defn load [dependencies]
  (->> dependencies
       &/->seq
       (map #(->> ^String % (new File) unpackage))
       (reduce merge {})))