mirror of
https://github.com/penpot/penpot.git
synced 2025-05-17 13:26:11 +02:00
128 lines
3.4 KiB
Clojure
128 lines
3.4 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) UXBOX Labs SL
|
|
|
|
(ns app.util.bytes
|
|
"Bytes & Byte Streams helpers"
|
|
(:require
|
|
[clojure.java.io :as io]
|
|
[datoteka.fs :as fs]
|
|
[yetti.adapter :as yt])
|
|
(:import
|
|
com.github.luben.zstd.ZstdInputStream
|
|
com.github.luben.zstd.ZstdOutputStream
|
|
java.io.ByteArrayInputStream
|
|
java.io.ByteArrayOutputStream
|
|
java.io.DataInputStream
|
|
java.io.DataOutputStream
|
|
java.io.OutputStream
|
|
java.io.InputStream
|
|
java.lang.AutoCloseable
|
|
org.apache.commons.io.IOUtils
|
|
org.apache.commons.io.input.BoundedInputStream))
|
|
|
|
;; TODO: migrate to datoteka.io
|
|
|
|
(set! *warn-on-reflection* true)
|
|
|
|
(def ^:const default-buffer-size
|
|
(:xnio/buffer-size yt/defaults))
|
|
|
|
(defn input-stream?
|
|
[s]
|
|
(instance? InputStream s))
|
|
|
|
(defn output-stream?
|
|
[s]
|
|
(instance? OutputStream s))
|
|
|
|
(defn data-input-stream?
|
|
[s]
|
|
(instance? DataInputStream s))
|
|
|
|
(defn data-output-stream?
|
|
[s]
|
|
(instance? DataOutputStream s))
|
|
|
|
(defn copy!
|
|
[src dst & {:keys [offset size buffer-size]
|
|
:or {offset 0 buffer-size default-buffer-size}}]
|
|
(let [^bytes buff (byte-array buffer-size)]
|
|
(if size
|
|
(IOUtils/copyLarge ^InputStream src ^OutputStream dst (long offset) (long size) buff)
|
|
(IOUtils/copyLarge ^InputStream src ^OutputStream dst buff))))
|
|
|
|
(defn write-to-file!
|
|
[src dst & {:keys [size]}]
|
|
(with-open [^OutputStream output (io/output-stream dst)]
|
|
(cond
|
|
(bytes? src)
|
|
(if size
|
|
(with-open [^InputStream input (ByteArrayInputStream. ^bytes src)]
|
|
(with-open [^InputStream input (BoundedInputStream. input (or size (alength ^bytes src)))]
|
|
(copy! input output :size size)))
|
|
|
|
(do
|
|
(IOUtils/writeChunked ^bytes src output)
|
|
(.flush ^OutputStream output)
|
|
(alength ^bytes src)))
|
|
|
|
(instance? InputStream src)
|
|
(copy! src output :size size)
|
|
|
|
:else
|
|
(throw (IllegalArgumentException. "invalid arguments")))))
|
|
|
|
(defn read-as-bytes
|
|
"Read input stream as byte array."
|
|
[input & {:keys [size]}]
|
|
(cond
|
|
(instance? InputStream input)
|
|
(with-open [output (ByteArrayOutputStream. (or size (.available ^InputStream input)))]
|
|
(copy! input output :size size)
|
|
(.toByteArray output))
|
|
|
|
(fs/path? input)
|
|
(with-open [input (io/input-stream input)
|
|
output (ByteArrayOutputStream. (or size (.available input)))]
|
|
(copy! input output :size size)
|
|
(.toByteArray output))
|
|
|
|
:else
|
|
(throw (IllegalArgumentException. "invalid arguments"))))
|
|
|
|
(defn bytes-input-stream
|
|
"Creates an instance of ByteArrayInputStream."
|
|
[^bytes data]
|
|
(ByteArrayInputStream. data))
|
|
|
|
(defn bounded-input-stream
|
|
[input size & {:keys [close?] :or {close? true}}]
|
|
(doto (BoundedInputStream. ^InputStream input ^long size)
|
|
(.setPropagateClose close?)))
|
|
|
|
(defn zstd-input-stream
|
|
^InputStream
|
|
[input]
|
|
(ZstdInputStream. ^InputStream input))
|
|
|
|
(defn zstd-output-stream
|
|
^OutputStream
|
|
[output & {:keys [level] :or {level 0}}]
|
|
(ZstdOutputStream. ^OutputStream output (int level)))
|
|
|
|
(defn data-input-stream
|
|
^DataInputStream
|
|
[input]
|
|
(DataInputStream. ^InputStream input))
|
|
|
|
(defn data-output-stream
|
|
^DataOutputStream
|
|
[output]
|
|
(DataOutputStream. ^OutputStream output))
|
|
|
|
(defn close!
|
|
[^AutoCloseable stream]
|
|
(.close stream))
|