diff options
author | Stuart Sierra <mail@stuartsierra.com> | 2010-01-31 10:52:19 -0500 |
---|---|---|
committer | Stuart Sierra <mail@stuartsierra.com> | 2010-01-31 10:52:19 -0500 |
commit | 687df969765631f4db641df4dae313246416561a (patch) | |
tree | 6a650e6f987f9404ecb28bcd3671a0e05a5b21a1 /src | |
parent | 23ef0425a6ce246ab2b2408f549d0476083dd5cc (diff) |
c.c.json: use PrintWriter directly; even faster
Diffstat (limited to 'src')
-rw-r--r-- | src/main/clojure/clojure/contrib/json.clj | 113 |
1 files changed, 61 insertions, 52 deletions
diff --git a/src/main/clojure/clojure/contrib/json.clj b/src/main/clojure/clojure/contrib/json.clj index 5bcedfce..7884f3a2 100644 --- a/src/main/clojure/clojure/contrib/json.clj +++ b/src/main/clojure/clojure/contrib/json.clj @@ -14,11 +14,12 @@ (ns #^{:author "Stuart Sierra" :doc "JavaScript Object Notation (JSON) parser/writer. See http://www.json.org/ - To write JSON, use json-str, write-json, or print-json. + To write JSON, use json-str, write-json, or write-json. To read JSON, use read-json."} clojure.contrib.json (:require [clojure.contrib.java-utils :as j]) - (:import (java.io PushbackReader StringReader Reader EOFException))) + (:import (java.io PrintWriter PushbackReader StringWriter + StringReader Reader EOFException))) ;;; JSON READER @@ -199,11 +200,11 @@ ;;; JSON PRINTER -(defprotocol Print-JSON - (print-json [object] - "Print object to *out* as JSON")) +(defprotocol Write-JSON + (write-json [object out] + "Print object to PrintWriter out as JSON")) -(defn- print-json-string [#^CharSequence s] +(defn- write-json-string [#^CharSequence s #^PrintWriter out] (let [sb (StringBuilder. #^Integer (count s))] (.append sb \") (dotimes [i (count s)] @@ -224,72 +225,80 @@ ;; Any other character is Hexadecimal-escaped :else (.append sb (format "\\u%04x" cp))))) (.append sb \") - (print (str sb)))) + (.print out (str sb)))) -(defn- print-json-object [m] - (print \{) +(defn- write-json-object [m #^PrintWriter out] + (.print out \{) (loop [x m] (when (seq m) (let [[k v] (first x)] (when (nil? k) (throw (Exception. "JSON object keys cannot be nil/null"))) - (print-json (j/as-str k)) - (print \:) - (print-json v)) + (.print out \") + (.print out (j/as-str k)) + (.print out \") + (.print out \:) + (write-json v out)) (let [nxt (next x)] (when (seq nxt) - (print \,) + (.print out \,) (recur nxt))))) - (print \})) + (.print out \})) -(defn- print-json-array [s] - (print \[) +(defn- write-json-array [s #^PrintWriter out] + (.print out \[) (loop [x s] (when (seq x) (let [fst (first x) nxt (next x)] - (print-json fst) + (write-json fst out) (when (seq nxt) - (print \,) + (.print out \,) (recur nxt))))) - (print \])) - -(defn- print-json-bignum [x] - (print (str x))) - -(extend nil Print-JSON - {:print-json (fn [x] (print "null"))}) -(extend clojure.lang.Named Print-JSON - {:print-json (fn [x] (print-json (name x)))}) -(extend java.lang.Boolean Print-JSON - {:print-json pr}) -(extend java.lang.Number Print-JSON - {:print-json pr}) -(extend java.math.BigInteger Print-JSON - {:print-json print-json-bignum}) -(extend java.math.BigDecimal Print-JSON - {:print-json print-json-bignum}) -(extend java.lang.CharSequence Print-JSON - {:print-json print-json-string}) -(extend java.util.Map Print-JSON - {:print-json print-json-object}) -(extend java.util.Collection Print-JSON - {:print-json print-json-array}) -(extend clojure.lang.ISeq Print-JSON - {:print-json print-json-array}) -(extend java.lang.Object Print-JSON - {:print-json (fn [x] + (.print out \])) + +(defn- write-json-bignum [x #^PrintWriter out] + (.print out (str x))) + +(defn- write-json-plain [x #^PrintWriter out] + (.print out x)) + +(extend nil Write-JSON + {:write-json (fn [x #^PrintWriter out] (.print out "null"))}) +(extend clojure.lang.Named Write-JSON + {:write-json (fn [x #^PrintWriter out] + (write-json-string (name x) out))}) +(extend java.lang.Boolean Write-JSON + {:write-json write-json-plain}) +(extend java.lang.Number Write-JSON + {:write-json write-json-plain}) +(extend java.math.BigInteger Write-JSON + {:write-json write-json-bignum}) +(extend java.math.BigDecimal Write-JSON + {:write-json write-json-bignum}) +(extend java.lang.CharSequence Write-JSON + {:write-json write-json-string}) +(extend java.util.Map Write-JSON + {:write-json write-json-object}) +(extend java.util.Collection Write-JSON + {:write-json write-json-array}) +(extend clojure.lang.ISeq Write-JSON + {:write-json write-json-array}) +(extend java.lang.Object Write-JSON + {:write-json (fn [x out] (if (.isArray (class x)) - (print-json (seq x)) + (write-json (seq x) out) (throw (Exception. "Don't know how to print JSON of " (class x)))))}) (defn json-str "Converts x to a JSON-formatted string." [x] - (with-out-str (print-json x))) + (let [sw (StringWriter.) + out (PrintWriter. sw)] + (write-json x out) + (.toString sw))) -(defn write-json - "Writes JSON-formatted text to out." - [x out] - (binding [*out* out] - (print-json x))) +(defn print-json + "Write JSON-formatted output to *out*" + [x] + (write-json x *out*)) |