Expose low-level fns: freeze-to-stream!, thaw-from-stream!

This commit is contained in:
Peter Taoussanis 2013-07-25 15:51:45 +07:00
parent a8b1686a54
commit 69611657c7

View file

@ -78,13 +78,20 @@
(defmacro ^:private write-utf8 [s x] `(write-bytes ~s (.getBytes ~x "UTF-8"))) (defmacro ^:private write-utf8 [s x] `(write-bytes ~s (.getBytes ~x "UTF-8")))
(defmacro ^:private freeze-to-stream (defmacro ^:private freeze-to-stream
"Like `freeze-to-stream*` but with metadata support." "Like `freeze-to-stream*` but with metadata support."
[x s] [s x]
`(let [x# ~x s# ~s] `(let [x# ~x s# ~s]
(if-let [m# (meta x#)] (when-let [m# (meta x#)]
(do (write-id s# ~id-meta) (write-id s# ~id-meta)
(freeze-to-stream* m# s#))) (freeze-to-stream* m# s#))
(freeze-to-stream* x# s#))) (freeze-to-stream* x# s#)))
(defn freeze-to-stream!
"Low-level API. Serializes arg (any Clojure data type) to a DataOutputStream."
[^DataOutputStream data-output-stream x & [{:keys [print-dup?]
:or {print-dup? true}}]]
(binding [*print-dup* print-dup?]
(freeze-to-stream data-output-stream x)))
(defmacro ^:private freezer (defmacro ^:private freezer
"Helper to extend Freezable protocol." "Helper to extend Freezable protocol."
[type id & body] [type id & body]
@ -99,7 +106,7 @@
[type id & body] [type id & body]
`(freezer ~type ~id `(freezer ~type ~id
(.writeInt ~'s (count ~'x)) (.writeInt ~'s (count ~'x))
(doseq [i# ~'x] (freeze-to-stream i# ~'s)))) (doseq [i# ~'x] (freeze-to-stream ~'s i#))))
(defmacro ^:private kv-freezer (defmacro ^:private kv-freezer
"Extends Freezable to key-value collection types." "Extends Freezable to key-value collection types."
@ -107,8 +114,8 @@
`(freezer ~type ~id `(freezer ~type ~id
(.writeInt ~'s (* 2 (count ~'x))) (.writeInt ~'s (* 2 (count ~'x)))
(doseq [[k# v#] ~'x] (doseq [[k# v#] ~'x]
(freeze-to-stream k# ~'s) (freeze-to-stream ~'s k#)
(freeze-to-stream v# ~'s)))) (freeze-to-stream ~'s v#))))
(freezer (Class/forName "[B") id-bytes (write-bytes s ^bytes x)) (freezer (Class/forName "[B") id-bytes (write-bytes s ^bytes x))
(freezer nil id-nil) (freezer nil id-nil)
@ -173,7 +180,7 @@
(when legacy-mode (assert-legacy-args compressor password)) (when legacy-mode (assert-legacy-args compressor password))
(let [ba (ByteArrayOutputStream.) (let [ba (ByteArrayOutputStream.)
stream (DataOutputStream. ba)] stream (DataOutputStream. ba)]
(binding [*print-dup* print-dup?] (freeze-to-stream x stream)) (freeze-to-stream! stream x {:print-dup? print-dup?})
(let [ba (.toByteArray ba) (let [ba (.toByteArray ba)
ba (if compressor (compression/compress compressor ba) ba) ba (if compressor (compression/compress compressor ba) ba)
ba (if password (encryption/encrypt encryptor password ba) ba)] ba (if password (encryption/encrypt encryptor password ba) ba)]
@ -254,6 +261,13 @@
(throw (Exception. (str "Failed to thaw unknown type ID: " type-id)))))) (throw (Exception. (str "Failed to thaw unknown type ID: " type-id))))))
(defn thaw-from-stream!
"Low-level API. Deserializes a frozen object from given DataInputStream to its
original Clojure data type."
[data-input-stream & [{:keys [read-eval?]}]]
(binding [*read-eval* read-eval?]
(thaw-from-stream data-input-stream)))
(defn- try-parse-header [ba] (defn- try-parse-header [ba]
(when-let [[head-ba data-ba] (utils/ba-split ba 4)] (when-let [[head-ba data-ba] (utils/ba-split ba 4)]
(let [[head-sig* [meta-id]] (utils/ba-split head-ba 3)] (let [[head-sig* [meta-id]] (utils/ba-split head-ba 3)]
@ -261,8 +275,9 @@
[data-ba (head-meta meta-id {:unrecognized-header? true})])))) [data-ba (head-meta meta-id {:unrecognized-header? true})]))))
(defn thaw (defn thaw
"Deserializes frozen bytes to their original Clojure data type. Supports data "Deserializes a frozen object from given byte array to its original Clojure
frozen with current and all previous versions of Nippy. data type. Supports data frozen with current and all previous versions of
Nippy.
WARNING: Enabling `:read-eval?` can lead to security vulnerabilities unless WARNING: Enabling `:read-eval?` can lead to security vulnerabilities unless
you are sure you know what you're doing." you are sure you know what you're doing."
@ -284,7 +299,7 @@
ba (if password (encryption/decrypt encryptor password ba) ba) ba (if password (encryption/decrypt encryptor password ba) ba)
ba (if compressor (compression/decompress compressor ba) ba) ba (if compressor (compression/decompress compressor ba) ba)
stream (DataInputStream. (ByteArrayInputStream. ba))] stream (DataInputStream. (ByteArrayInputStream. ba))]
(binding [*read-eval* read-eval?] (thaw-from-stream stream))) (thaw-from-stream! stream {:read-eval? read-eval?}))
(catch Exception e (catch Exception e
(cond (cond
password (ex "Wrong password/encryptor?" e) password (ex "Wrong password/encryptor?" e)