Generalise to allow serialising from/to any DataInput/DataOutput. (cmf)

This commit is contained in:
Peter Taoussanis 2014-01-22 14:07:20 +07:00
parent b413adc62a
commit 87fcd3a9c6

View file

@ -8,7 +8,8 @@
(compression :as compression :refer (snappy-compressor)) (compression :as compression :refer (snappy-compressor))
(encryption :as encryption :refer (aes128-encryptor))]) (encryption :as encryption :refer (aes128-encryptor))])
(:import [java.io ByteArrayInputStream ByteArrayOutputStream DataInputStream (:import [java.io ByteArrayInputStream ByteArrayOutputStream DataInputStream
DataOutputStream Serializable ObjectOutputStream ObjectInputStream] DataOutputStream Serializable ObjectOutputStream ObjectInputStream
DataOutput DataInput]
[java.lang.reflect Method] [java.lang.reflect Method]
[java.util Date UUID] [java.util Date UUID]
[clojure.lang Keyword BigInt Ratio [clojure.lang Keyword BigInt Ratio
@ -114,7 +115,7 @@
(defmacro ^:private freezer [type id & body] (defmacro ^:private freezer [type id & body]
`(extend-type ~type `(extend-type ~type
Freezable Freezable
(~'freeze-to-stream* [~'x ~(with-meta 's {:tag 'DataOutputStream})] (~'freeze-to-stream* [~'x ~(with-meta 's {:tag 'DataOutput})]
(write-id ~'s ~id) (write-id ~'s ~id)
~@body))) ~@body)))
@ -206,7 +207,7 @@
;; interfering with higher-level implementations, Ref. http://goo.gl/6f7SKl ;; interfering with higher-level implementations, Ref. http://goo.gl/6f7SKl
(extend-type Object (extend-type Object
Freezable Freezable
(freeze-to-stream* [x ^DataOutputStream s] (freeze-to-stream* [x ^DataOutput s]
(cond (cond
(utils/serializable? x) ; Fallback #1: Java's Serializable interface (utils/serializable? x) ; Fallback #1: Java's Serializable interface
(do (when-debug-mode (do (when-debug-mode
@ -240,9 +241,9 @@
(declare assert-legacy-args) ; Deprecated (declare assert-legacy-args) ; Deprecated
(defn freeze-to-stream! (defn freeze-to-stream!
"Low-level API. Serializes arg (any Clojure data type) to a DataOutputStream." "Low-level API. Serializes arg (any Clojure data type) to a DataOutput."
[^DataOutputStream data-output-stream x & _] [^DataOutput data-output x & _]
(freeze-to-stream data-output-stream x)) (freeze-to-stream data-output x))
(defn freeze (defn freeze
"Serializes arg (any Clojure data type) to a byte array. For custom types "Serializes arg (any Clojure data type) to a byte array. For custom types
@ -272,7 +273,7 @@
`(let [s# ~s `(let [s# ~s
size# (.readInt s#) size# (.readInt s#)
ba# (byte-array size#)] ba# (byte-array size#)]
(.read s# ba# 0 size#) ba#)) (.readFully s# ba# 0 size#) ba#))
(defmacro ^:private read-biginteger [s] `(BigInteger. (read-bytes ~s))) (defmacro ^:private read-biginteger [s] `(BigInteger. (read-bytes ~s)))
(defmacro ^:private read-utf8 [s] `(String. (read-bytes ~s) "UTF-8")) (defmacro ^:private read-utf8 [s] `(String. (read-bytes ~s) "UTF-8"))
@ -287,7 +288,7 @@
(declare ^:private custom-readers) (declare ^:private custom-readers)
(defn- thaw-from-stream (defn- thaw-from-stream
[^DataInputStream s] [^DataInput s]
(let [type-id (.readByte s)] (let [type-id (.readByte s)]
(try (try
(when-debug-mode (when-debug-mode
@ -376,10 +377,10 @@
(throw (Exception. (format "Thaw failed against type-id: %s" type-id) e)))))) (throw (Exception. (format "Thaw failed against type-id: %s" type-id) e))))))
(defn thaw-from-stream! (defn thaw-from-stream!
"Low-level API. Deserializes a frozen object from given DataInputStream to its "Low-level API. Deserializes a frozen object from given DataInput to its
original Clojure data type." original Clojure data type."
[data-input-stream & _] [data-input & _]
(thaw-from-stream data-input-stream)) (thaw-from-stream data-input))
(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)]
@ -480,7 +481,7 @@
(assert (and (>= custom-type-id 1) (<= custom-type-id 128))) (assert (and (>= custom-type-id 1) (<= custom-type-id 128)))
`(extend-type ~type `(extend-type ~type
Freezable Freezable
(~'freeze-to-stream* [~x ~(with-meta stream {:tag 'java.io.DataOutputStream})] (~'freeze-to-stream* [~x ~(with-meta stream {:tag 'java.io.DataOutput})]
(write-id ~stream ~(int (- custom-type-id))) (write-id ~stream ~(int (- custom-type-id)))
~@body))) ~@body)))
@ -493,7 +494,7 @@
[custom-type-id [stream] & body] [custom-type-id [stream] & body]
(assert (and (>= custom-type-id 1) (<= custom-type-id 128))) (assert (and (>= custom-type-id 1) (<= custom-type-id 128)))
`(swap! custom-readers assoc ~(int (- custom-type-id)) `(swap! custom-readers assoc ~(int (- custom-type-id))
(fn [~(with-meta stream {:tag 'java.io.DataInputStream})] (fn [~(with-meta stream {:tag 'java.io.DataInput})]
~@body))) ~@body)))
(comment (defrecord MyType [data]) (comment (defrecord MyType [data])