pax_global_header 0000666 0000000 0000000 00000000064 13076023672 0014520 g ustar 00root root 0000000 0000000 52 comment=46489a7dd5404cb81e1ab127b66b58f2aafb2a5e
cheshire-5.7.1/ 0000775 0000000 0000000 00000000000 13076023672 0013324 5 ustar 00root root 0000000 0000000 cheshire-5.7.1/.gitignore 0000664 0000000 0000000 00000000174 13076023672 0015316 0 ustar 00root root 0000000 0000000 lib/*
multi-lib/*
coref
classes/*
.lein-failures
.lein-deps-sum
target/*
pom.xml*
doc*
.lein*
.nrepl*
.idea
*.iml
.DS_Store
cheshire-5.7.1/.travis.yml 0000664 0000000 0000000 00000000211 13076023672 0015427 0 ustar 00root root 0000000 0000000 language: clojure
lein: lein2
script: lein2 all test :all
branches:
only:
- master
jdk:
- oraclejdk8
- openjdk7
- oraclejdk7
cheshire-5.7.1/ChangeLog.md 0000664 0000000 0000000 00000004543 13076023672 0015503 0 ustar 00root root 0000000 0000000 ## Changes between Cheshire 5.6.3 and 5.6.2
* Fix float coercion when encoding
## Changes between Cheshire 5.6.2 and 5.6.1
* Fix type hints for newer clojure version
* Bump Jackson dependencies
## Changes between Cheshire 5.6.1 and 5.6.0
* Fix javac target for 1.6 compatibility
## Changes between Cheshire 5.6.0 and 5.5.0
* Fixes for type hinting
* Make :pretty option configurable to use custom pretty printer
## Changes between Cheshire 5.5.0 and 5.5.0
* Bump Jackson dependencies
## Changes between Cheshire 5.4.0 and 5.3.2
* Add CBOR encoding/decoding
* Add docstrings for clojure-json aliases
* Add default encoder for java.lang.Character
* Add sequential write support
* Bump dependencies
## Changes between Cheshire 5.3.1 and 5.3.0
* Fix string parsing for 1 and 2 arity methods
* Bump Jackson to 2.3.1
## Changes between Cheshire 5.3.0 and 5.2.0
* Dependencies have been bumped
* Parse streams strictly by default to avoid scoping issues
## Changes between Cheshire 5.2.0 and 5.1.2
* Bump tigris to 0.1.1 to use PushbackReader
* Lazily decode top-level arrays (thanks ztellman)
## Changes between Cheshire 5.1.2 and 5.1.1
* Add experimental namespace
* Bump Jackson deps to 2.2.1
## Changes between Cheshire 5.1.1 and 5.1.0
* Remove all reflection (thanks amalloy)
* Fixed custom encoder helpers (thanks lynaghk)
## Changes between Cheshire 5.1.0 and 5.0.2
* Allow custom keyword function for encoding (thanks goodwink)
## Changes between Cheshire 5.0.2 and 5.0.1
* Bump Jackson dependency from 2.1.1 to 2.1.3
* Add more type hinting (thanks to ztellman)
## Changes between Cheshire 5.0.0 and 5.0.1
* Protocol custom encoders now take precedence over regular map
encoders.
* Benchmarking is now a separate lein command, not a test selector.
## Changes between Cheshire 5.0.0 and 4.0.x
### Custom Encoders Changes
Custom encoder functions were moved to the `cheshire.generate` namespace:
* `cheshire.custom/add-encoder` is now `cheshire.generate/add-encoder`
* `cheshire.custom/remove-encoder` is now `cheshire.generate/remove-encoder`
In addition, `cheshire.custom/encode` and `cheshire.custom/decode` are no longer
necessary. Use `cheshire.core/encode` and `cheshire.core/decode` instead and
those functions will pick up custom encoders while still preserving the same
level of efficiency.
GH issue: [#32](https://github.com/dakrone/cheshire/issues/32).
cheshire-5.7.1/LICENSE 0000664 0000000 0000000 00000002046 13076023672 0014333 0 ustar 00root root 0000000 0000000 Copyright (c) 2011 Matthew Lee Hinman
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cheshire-5.7.1/README.md 0000664 0000000 0000000 00000025270 13076023672 0014611 0 ustar 00root root 0000000 0000000 # Cheshire
'Cheshire Puss,' she began, rather timidly, as she did not at all know
whether it would like the name: however, it only grinned a little
wider. 'Come, it's pleased so far,' thought Alice, and she went
on. 'Would you tell me, please, which way I ought to go from here?'
'That depends a good deal on where you want to get to,' said the Cat.
'I don't much care where--' said Alice.
'Then it doesn't matter which way you go,' said the Cat.
'--so long as I get SOMEWHERE,' Alice added as an explanation.
'Oh, you're sure to do that,' said the Cat, 'if you only walk long
enough.'
Cheshire is fast JSON encoding, based off of clj-json and
clojure-json, with additional features like Date/UUID/Set/Symbol
encoding and SMILE support.
[Clojure code with docs](http://dakrone.github.com/cheshire/)
[](http://travis-ci.org/dakrone/cheshire)
## Why?
clojure-json had really nice features (custom encoders), but was slow;
clj-json had no features, but was fast. Cheshire encodes JSON fast,
with added support for more types and the ability to use custom
encoders.
## Usage
```clojure
[cheshire "5.7.1"]
;; Cheshire v5.7.1 uses Jackson 2.8.6
;; In your ns statement:
(ns my.ns
(:require [cheshire.core :refer :all]))
```
### Encoding
```clojure
;; generate some json
(generate-string {:foo "bar" :baz 5})
;; write some json to a stream
(generate-stream {:foo "bar" :baz 5} (clojure.java.io/writer "/tmp/foo"))
;; generate some SMILE
(generate-smile {:foo "bar" :baz 5})
;; generate some JSON with Dates
;; the Date will be encoded as a string using
;; the default date format: yyyy-MM-dd'T'HH:mm:ss'Z'
(generate-string {:foo "bar" :baz (java.util.Date. 0)})
;; generate some JSON with Dates with custom Date encoding
(generate-string {:baz (java.util.Date. 0)} {:date-format "yyyy-MM-dd"})
;; generate some JSON with pretty formatting
(generate-string {:foo "bar" :baz {:eggplant [1 2 3]}} {:pretty true})
;; {
;; "foo" : "bar",
;; "baz" : {
;; "eggplant" : [ 1, 2, 3 ]
;; }
;; }
;; generate JSON escaping UTF-8
(generate-string {:foo "It costs £100"} {:escape-non-ascii true})
;; => "{\"foo\":\"It costs \\u00A3100\"}"
;; generate JSON and munge keys with a custom function
(generate-string {:foo "bar"} {:key-fn (fn [k] (.toUpperCase (name k)))})
;; => "{\"FOO\":\"bar\"}"
```
In the event encoding fails, Cheshire will throw a JsonGenerationException.
#### Custom Pretty Printing Options
If Jackson's default pretty printing library is not what you desire, you can
manually create your own pretty printing class and pass to the `generate-string`
or `encode` methods:
```clojure
(let [my-pretty-printer (create-pretty-printer
(assoc default-pretty-print-options
:indent-arrays? true))]
(generate-string {:foo [1 2 3]} {:pretty my-pretty-printer}))
```
See the `default-pretty-print-options` for a list of options that can be
changed.
### Decoding
```clojure
;; parse some json
(parse-string "{\"foo\":\"bar\"}")
;; => {"foo" "bar"}
;; parse some json and get keywords back
(parse-string "{\"foo\":\"bar\"}" true)
;; => {:foo "bar"}
;; parse some json and munge keywords with a custom function
(parse-string "{\"foo\":\"bar\"}" (fn [k] (keyword (.toUpperCase k))))
;; => {:FOO "bar"}
;; top-level strings are valid JSON too
(parse-string "\"foo\"")
;; => "foo"
;; parse some SMILE (keywords option also supported)
(parse-smile )
;; parse a stream (keywords option also supported)
(parse-stream (clojure.java.io/reader "/tmp/foo"))
;; parse a stream lazily (keywords option also supported)
(parsed-seq (clojure.java.io/reader "/tmp/foo"))
;; parse a SMILE stream lazily (keywords option also supported)
(parsed-smile-seq (clojure.java.io/reader "/tmp/foo"))
```
In 2.0.4 and up, Cheshire allows passing in a
function to specify what kind of types to return, like so:
```clojure
;; In this example a function that checks for a certain key
(decode "{\"myarray\":[2,3,3,2],\"myset\":[1,2,2,1]}" true
(fn [field-name]
(if (= field-name "myset")
#{}
[])))
;; => {:myarray [2 3 3 2], :myset #{1 2}}
```
The type must be "transient-able", so use either #{} or []
### Custom Encoders
Custom encoding is supported from 2.0.0 and up, if you encounter a
bug, please open a github issue. From 5.0.0 onwards, custom encoding
has been moved to be part of the core namespace (not requiring a
namespace change)
```clojure
;; Custom encoders allow you to swap out the api for the fast
;; encoder with one that is slightly slower, but allows custom
;; things to be encoded:
(ns myns
(:require [cheshire.core :refer :all]
[cheshire.generate :refer [add-encoder encode-str remove-encoder]]))
;; First, add a custom encoder for a class:
(add-encoder java.awt.Color
(fn [c jsonGenerator]
(.writeString jsonGenerator (str c))))
;; There are also helpers for common encoding actions:
(add-encoder java.net.URL encode-str)
;; List of common encoders that can be used: (see generate.clj)
;; encode-nil
;; encode-number
;; encode-seq
;; encode-date
;; encode-bool
;; encode-named
;; encode-map
;; encode-symbol
;; encode-ratio
;; Then you can use encode from the custom namespace as normal
(encode (java.awt.Color. 1 2 3))
;; => "java.awt.Color[r=1,g=2,b=3]"
;; Custom encoders can also be removed:
(remove-encoder java.awt.Color)
;; Decoding remains the same, you are responsible for doing custom decoding.
```
NOTE: `cheshire.custom` has been deprecated in version 5.0.0
Custom and Core encoding have been combined in Cheshire 5.0.0, so
there is no longer any need to require a different namespace depending
on what you would like to use.
### Aliases
There are also a few aliases for commonly used functions:
encode -> generate-string
encode-stream -> generate-stream
encode-smile -> generate-smile
decode -> parse-string
decode-stream -> parse-stream
decode-smile -> parse-smile
## Features
Cheshire supports encoding standard clojure datastructures, with a few
additions.
Cheshire encoding supports:
### Clojure data structures
- strings
- lists
- vectors
- sets
- maps
- symbols
- booleans
- keywords (qualified and unqualified)
- numbers (Integer, Long, BigInteger, BigInt, Double, Float, Ratio,
Short, Byte, primatives)
- clojure.lang.PersistentQueue
### Java classes
- Date
- UUID
- java.sql.Timestamp
- any java.util.Set
- any java.util.Map
- any java.util.List
### Custom class encoding while still being fast
### Also supports
- Stream encoding/decoding
- Lazy decoding
- Pretty-printing JSON generation
- Unicode escaping
- Custom keyword coercion
- Arbitrary precision for decoded values:
Cheshire will automatically use a BigInteger if needed for
non-floating-point numbers, however, for floating-point numbers,
Doubles will be used unless the `*use-bigdecimals?*` symbol is bound
to true:
```clojure
(ns foo.bar
(require [cheshire.core :as json]
[cheshire.parse :as parse]))
(json/decode "111111111111111111111111111111111.111111111111111111111111111111111111")
;; => 1.1111111111111112E32 (a Double)
(binding [parse/*use-bigdecimals?* true]
(json/decode "111111111111111111111111111111111.111111111111111111111111111111111111"))
;; => 111111111111111111111111111111111.111111111111111111111111111111111111M (a BigDecimal)
```
- Replacing default encoders for builtin types
- [SMILE encoding/decoding](http://wiki.fasterxml.com/SmileFormatSpec)
## Change Log
[Change log](https://github.com/dakrone/cheshire/blob/master/ChangeLog.md) is available on GitHub.
## Speed
Cheshire is about twice as fast as data.json.
Check out the benchmarks in `cheshire.test.benchmark`; or run `lein
benchmark`. If you have scenarios where Cheshire is not performing as
well as expected (compared to a different library), please let me
know.
## Experimental things
In the `cheshire.experimental` namespace:
```
$ echo "Hi. \"THIS\" is a string.\\yep." > /tmp/foo
$ lein repl
user> (use 'cheshire.experimental)
nil
user> (use 'clojure.java.io)
nil
user> (println (slurp (encode-large-field-in-map {:id "10"
:things [1 2 3]
:body "I'll be removed"}
:body
(input-stream (file "/tmp/foo")))))
{"things":[1,2,3],"id":"10","body":"Hi. \"THIS\" is a string.\\yep.\n"}
nil
```
`encode-large-field-in-map` is used for streamy JSON encoding where
you want to JSON encode a map, but don't want the map in memory all at
once (it returns a stream). Check out the docstring for full usage.
It's experimental, like the name says. Based on [Tigris](http://github.com/dakrone/tigris).
## Advanced customization for factories
See
[this](http://fasterxml.github.com/jackson-core/javadoc/2.1.1/com/fasterxml/jackson/core/JsonFactory.Feature.html)
and
[this](http://fasterxml.github.com/jackson-core/javadoc/2.1.1/com/fasterxml/jackson/core/JsonParser.Feature.html)
for a list of features that can be customized if desired. A custom
factory can be used like so:
```clojure
(ns myns
(:require [cheshire.core :as core]
[cheshire.factory :as factory]))
(binding [factory/*json-factory* (factory/make-json-factory
{:allow-non-numeric-numbers true})]
(json/decode "{\"foo\":NaN}" true))))))
```
See the `default-factory-options` map in
[factory.clj](https://github.com/dakrone/cheshire/blob/master/src/cheshire/factory.clj)
for a full list of configurable options. Smile factories can also be
created, and factories work exactly the same with custom encoding.
## Future Ideas/TODOs
- move away from using Java entirely, use Protocols for the
custom encoder (see custom.clj)
- allow custom encoders (see custom.clj)
- figure out a way to encode namespace-qualified keywords
- look into overriding the default encoding handlers with custom handlers
- better handling when java numbers overflow ECMAScript's numbers
(-2^31 to (2^31 - 1))
- handle encoding java.sql.Timestamp the same as
java.util.Date
- add benchmarking
- get criterium benchmarking ignored for 1.2.1 profile
- look into faster exception handling by pre-allocating an exception
object instead of creating one on-the-fly (maybe ask Steve?)
- make it as fast as possible (ongoing)
## License
Release under the MIT license. See LICENSE for the full license.
## Thanks
Thanks go to Mark McGranaghan for clj-json and Jim Duey for the name
suggestion. :)
cheshire-5.7.1/benchmarks/ 0000775 0000000 0000000 00000000000 13076023672 0015441 5 ustar 00root root 0000000 0000000 cheshire-5.7.1/benchmarks/cheshire/ 0000775 0000000 0000000 00000000000 13076023672 0017233 5 ustar 00root root 0000000 0000000 cheshire-5.7.1/benchmarks/cheshire/test/ 0000775 0000000 0000000 00000000000 13076023672 0020212 5 ustar 00root root 0000000 0000000 cheshire-5.7.1/benchmarks/cheshire/test/benchmark.clj 0000664 0000000 0000000 00000010517 13076023672 0022642 0 ustar 00root root 0000000 0000000 (ns cheshire.test.benchmark
(:use [clojure.test])
(:require [cheshire.core :as core]
[cheshire.custom :as old]
[cheshire.generate :as custom]
[clojure.data.json :as cj]
[clojure.java.io :refer [file input-stream resource]]
[clj-json.core :as clj-json]
[criterium.core :as bench])
(:import (java.util.zip GZIPInputStream)))
;; These tests just print out results, nothing else, they also
;; currently don't work with clojure 1.2 (but the regular tests do)
(def test-obj {"int" 3
"boolean" true
"LongObj" (Long/parseLong "2147483647")
"double" 1.23
"nil" nil
"string" "string"
"vec" [1 2 3]
"map" {"a" "b"}
"list" '("a" "b")
"set" #{"a" "b"}
"keyword" :foo})
(def test-pretty-opts
{:indentation 4
:indent-arrays? true
:object-field-value-separator ": "})
(def big-test-obj
(-> "test/all_month.geojson.gz"
file
input-stream
(GZIPInputStream. )
slurp
core/decode))
(deftest t-bench-clj-json
(println "-------- clj-json Benchmarks --------")
(bench/with-progress-reporting
(bench/quick-bench (clj-json/parse-string
(clj-json/generate-string test-obj)) :verbose))
(println "-------------------------------------"))
(deftest t-bench-clojure-json
(println "-------- Data.json Benchmarks -------")
(bench/with-progress-reporting
(bench/quick-bench (cj/read-str (cj/write-str test-obj)) :verbose))
(println "-------------------------------------"))
(deftest t-bench-core
(println "---------- Core Benchmarks ----------")
(bench/with-progress-reporting
(bench/bench (core/decode (core/encode test-obj)) :verbose))
(println "-------------------------------------"))
(deftest t-bench-pretty
(let [pretty-printer (core/create-pretty-printer test-pretty-opts)]
(println "------- PrettyPrint Benchmarks ------")
(println "........default pretty printer")
(bench/bench (core/encode test-obj {:pretty true}))
(println "........custom pretty printer")
(bench/bench (core/encode test-obj {:pretty pretty-printer}))))
(deftest t-bench-custom
(println "--------- Custom Benchmarks ---------")
(custom/add-encoder java.net.URL custom/encode-str)
(is (= "\"http://foo.com\"" (core/encode (java.net.URL. "http://foo.com"))))
(let [custom-obj (assoc test-obj "url" (java.net.URL. "http://foo.com"))]
(println "[+] Custom, all custom fields:")
(bench/with-progress-reporting
(bench/quick-bench (core/decode (core/encode custom-obj)) :verbose)))
(println "-------------------------------------"))
(deftest t-bench-custom-kw-coercion
(println "---- Custom keyword-fn Benchmarks ---")
(let [t (core/encode test-obj)]
(println "[+] (fn [k] (keyword k)) decode")
(bench/with-progress-reporting
(bench/quick-bench (core/decode t (fn [k] (keyword k)))))
(println "[+] basic 'true' keyword-fn decode")
(bench/with-progress-reporting
(bench/quick-bench (core/decode t true)))
(println "[+] no keyword-fn decode")
(bench/with-progress-reporting
(bench/quick-bench (core/decode t)))
(println "[+] (fn [k] (name k)) encode")
(bench/with-progress-reporting
(bench/quick-bench (core/encode test-obj {:key-fn (fn [k] (name k))})))
(println "[+] no keyword-fn encode")
(bench/with-progress-reporting
(bench/quick-bench (core/encode test-obj))))
(println "-------------------------------------"))
(deftest t-large-array
(println "-------- Large array parsing --------")
(let [test-array-json (core/encode (range 1024))]
(bench/with-progress-reporting
(bench/bench (pr-str (core/decode test-array-json)))))
(println "-------------------------------------"))
(deftest t-large-geojson-object
(println "------- Large GeoJSON parsing -------")
(println "[+] large geojson custom encode")
(bench/with-progress-reporting
(bench/quick-bench (old/encode big-test-obj)))
(println "[+] large geojson encode")
(bench/with-progress-reporting
(bench/quick-bench (core/encode big-test-obj)))
(println "[+] large geojson decode")
(let [s (core/encode big-test-obj)]
(bench/with-progress-reporting
(bench/quick-bench (core/decode s))))
(println "-------------------------------------"))
cheshire-5.7.1/project.clj 0000664 0000000 0000000 00000004464 13076023672 0015474 0 ustar 00root root 0000000 0000000 (defproject cheshire "5.7.1"
:description "JSON and JSON SMILE encoding, fast."
:url "https://github.com/dakrone/cheshire"
:license {:name "The MIT License"
:url "http://opensource.org/licenses/MIT"
:distribution :repo}
:global-vars {*warn-on-reflection* false}
:dependencies [[com.fasterxml.jackson.core/jackson-core "2.8.6"]
[com.fasterxml.jackson.dataformat/jackson-dataformat-smile "2.8.6"]
[com.fasterxml.jackson.dataformat/jackson-dataformat-cbor "2.8.6"]
[tigris "0.1.1"]]
:profiles {:dev {:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/test.generative "0.1.4"]]}
:1.3 {:dependencies [[org.clojure/clojure "1.3.0"]]}
:1.4 {:dependencies [[org.clojure/clojure "1.4.0"]]}
:1.5 {:dependencies [[org.clojure/clojure "1.5.1"]]}
:1.7 {:dependencies [[org.clojure/clojure "1.7.0"]]}
:1.8 {:dependencies [[org.clojure/clojure "1.8.0"]]}
:1.9 {:dependencies [[org.clojure/clojure "1.9.0-alpha7"]]}
:benchmark {:test-paths ["benchmarks"]
:jvm-opts ^:replace ["-Xms1g" "-Xmx1g" "-server"]
:dependencies [[criterium "0.4.4"]
[org.clojure/data.json "0.2.6"]
[clj-json "0.5.3"]]}}
:aliases {"all" ["with-profile" "dev,1.3:dev,1.4:dev,1.5:dev,1.7:dev,1.8:dev,1.9:dev"]
"benchmark" ["with-profile" "dev,benchmark" "test"]
"pretty-bench" ["with-profile" "dev,benchmark" "test" ":only"
"cheshire.test.benchmark/t-bench-pretty"]
"core-bench" ["with-profile" "dev,benchmark" "test" ":only"
"cheshire.test.benchmark/t-bench-core"]}
:test-selectors {:default #(and (not (:benchmark %))
(not (:generative %)))
:generative :generative
:all (constantly true)}
:plugins [[codox "0.6.3"]]
:java-source-paths ["src/java"]
:jvm-opts ["-Xmx512M"
;; "-XX:+PrintCompilation"
;; "-XX:+UnlockDiagnosticVMOptions"
;; "-XX:+PrintInlining"
]
:javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"])
cheshire-5.7.1/src/ 0000775 0000000 0000000 00000000000 13076023672 0014113 5 ustar 00root root 0000000 0000000 cheshire-5.7.1/src/cheshire/ 0000775 0000000 0000000 00000000000 13076023672 0015705 5 ustar 00root root 0000000 0000000 cheshire-5.7.1/src/cheshire/core.clj 0000664 0000000 0000000 00000035027 13076023672 0017336 0 ustar 00root root 0000000 0000000 (ns cheshire.core
"Main encoding and decoding namespace."
(:require [cheshire.factory :as factory]
[cheshire.generate :as gen]
[cheshire.generate-seq :as gen-seq]
[cheshire.parse :as parse])
(:import (com.fasterxml.jackson.core JsonParser JsonFactory
JsonGenerator PrettyPrinter
JsonGenerator$Feature)
(com.fasterxml.jackson.dataformat.smile SmileFactory)
(cheshire.prettyprint CustomPrettyPrinter)
(java.io StringWriter StringReader BufferedReader BufferedWriter
ByteArrayOutputStream OutputStream Reader Writer)))
(defonce default-pretty-print-options
{:indentation " "
:line-break "\n"
:indent-arrays? false
:indent-objects? true
:before-array-values nil
:after-array-values nil
:object-field-value-separator nil})
(defn create-pretty-printer
"Returns an instance of CustomPrettyPrinter based on the configuration
provided as argument"
[options]
(let [effective-opts (merge default-pretty-print-options options)
indentation (:indentation effective-opts)
line-break (:line-break effective-opts)
indent-arrays? (:indent-arrays? effective-opts)
indent-objects? (:indent-objects? effective-opts)
before-array-values (:before-array-values effective-opts)
after-array-values (:after-array-values effective-opts)
object-field-value-separator (:object-field-value-separator effective-opts)
indent-with (condp instance? indentation
String indentation
Long (apply str (repeat indentation " "))
Integer (apply str (repeat indentation " "))
" ")]
(-> (new CustomPrettyPrinter)
(.setIndentation indent-with line-break indent-objects? indent-arrays?)
(.setBeforeArrayValues before-array-values)
(.setAfterArrayValues after-array-values)
(.setObjectFieldValueSeparator object-field-value-separator))))
;; Generators
(defn generate-string
"Returns a JSON-encoding String for the given Clojure object. Takes an
optional date format string that Date objects will be encoded with.
The default date format (in UTC) is: yyyy-MM-dd'T'HH:mm:ss'Z'"
(^String [obj]
(generate-string obj nil))
(^String [obj opt-map]
(let [sw (StringWriter.)
generator (.createGenerator
^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Writer sw)
print-pretty (:pretty opt-map)]
(when print-pretty
(condp instance? print-pretty
Boolean
(.useDefaultPrettyPrinter generator)
clojure.lang.IPersistentMap
(.setPrettyPrinter generator (create-pretty-printer print-pretty))
PrettyPrinter
(.setPrettyPrinter generator print-pretty)
nil))
(when (:escape-non-ascii opt-map)
(.enable generator JsonGenerator$Feature/ESCAPE_NON_ASCII))
(gen/generate generator obj
(or (:date-format opt-map) factory/default-date-format)
(:ex opt-map)
(:key-fn opt-map))
(.flush generator)
(.toString sw))))
(defn generate-stream
"Returns a BufferedWriter for the given Clojure object with the JSON-encoded
data written to the writer. Takes an optional date format string that Date
objects will be encoded with.
The default date format (in UTC) is: yyyy-MM-dd'T'HH:mm:ss'Z'"
(^BufferedWriter [obj ^BufferedWriter writer]
(generate-stream obj writer nil))
(^BufferedWriter [obj ^BufferedWriter writer opt-map]
(let [generator (.createGenerator
^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Writer writer)
print-pretty (:pretty opt-map)]
(when print-pretty
(condp instance? print-pretty
Boolean
(.useDefaultPrettyPrinter generator)
clojure.lang.IPersistentMap
(.setPrettyPrinter generator (create-pretty-printer print-pretty))
PrettyPrinter
(.setPrettyPrinter generator print-pretty)
nil))
(when (:escape-non-ascii opt-map)
(.enable generator JsonGenerator$Feature/ESCAPE_NON_ASCII))
(gen/generate generator obj (or (:date-format opt-map)
factory/default-date-format)
(:ex opt-map)
(:key-fn opt-map))
(.flush generator)
writer)))
(defn create-generator [writer]
"Returns JsonGenerator for given writer."
(.createGenerator
^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Writer writer))
(def ^:dynamic ^JsonGenerator *generator*)
(def ^:dynamic *opt-map*)
(defmacro with-writer [[writer opt-map] & body]
"Start writing for series objects using the same json generator.
Takes writer and options map as arguments.
Expects its body as sequence of write calls.
Returns a given writer."
`(let [c-wr# ~writer]
(binding [*generator* (create-generator c-wr#)
*opt-map* ~opt-map]
~@body
(.flush *generator*)
c-wr#)))
(defn write
"Write given Clojure object as a piece of data within with-writer.
List of wholeness acceptable values:
- no value - the same as :all
- :all - write object in a regular way with start and end borders
- :start - write object with start border only
- :start-inner - write object and its inner object with start border only
- :end - write object with end border only."
([obj] (write obj nil))
([obj wholeness]
(gen-seq/generate *generator* obj (or (:date-format *opt-map*)
factory/default-date-format)
(:ex *opt-map*)
(:key-fn *opt-map*)
:wholeness wholeness)))
(defn generate-smile
"Returns a SMILE-encoded byte-array for the given Clojure object.
Takes an optional date format string that Date objects will be encoded with.
The default date format (in UTC) is: yyyy-MM-dd'T'HH:mm:ss'Z'"
(^bytes [obj]
(generate-smile obj nil))
(^bytes [obj opt-map]
(let [baos (ByteArrayOutputStream.)
generator (.createGenerator ^SmileFactory
(or factory/*smile-factory*
factory/smile-factory)
^OutputStream baos)]
(gen/generate generator obj (or (:date-format opt-map)
factory/default-date-format)
(:ex opt-map)
(:key-fn opt-map))
(.flush generator)
(.toByteArray baos))))
(defn generate-cbor
"Returns a CBOR-encoded byte-array for the given Clojure object.
Takes an optional date format string that Date objects will be encoded with.
The default date format (in UTC) is: yyyy-MM-dd'T'HH:mm:ss'Z'"
(^bytes [obj]
(generate-cbor obj nil))
(^bytes [obj opt-map]
(let [baos (ByteArrayOutputStream.)
generator (.createGenerator ^CBORFactory
(or factory/*cbor-factory*
factory/cbor-factory)
^OutputStream baos)]
(gen/generate generator obj (or (:date-format opt-map)
factory/default-date-format)
(:ex opt-map)
(:key-fn opt-map))
(.flush generator)
(.toByteArray baos))))
;; Parsers
(defn parse-string
"Returns the Clojure object corresponding to the given JSON-encoded string.
An optional key-fn argument can be either true (to coerce keys to keywords),
false to leave them as strings, or a function to provide custom coercion.
The array-coerce-fn is an optional function taking the name of an array field,
and returning the collection to be used for array values.
If the top-level object is an array, it will be parsed lazily (use
`parse-strict' if strict parsing is required for top-level arrays."
([string] (parse-string string nil nil))
([string key-fn] (parse-string string key-fn nil))
([^String string key-fn array-coerce-fn]
(when string
(parse/parse
(.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Reader (StringReader. string))
key-fn nil array-coerce-fn))))
;; Parsing strictly
(defn parse-string-strict
"Returns the Clojure object corresponding to the given JSON-encoded string.
An optional key-fn argument can be either true (to coerce keys to keywords),
false to leave them as strings, or a function to provide custom coercion.
The array-coerce-fn is an optional function taking the name of an array field,
and returning the collection to be used for array values.
Does not lazily parse top-level arrays."
([string] (parse-string-strict string nil nil))
([string key-fn] (parse-string-strict string key-fn nil))
([^String string key-fn array-coerce-fn]
(when string
(parse/parse-strict
(.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Writer (StringReader. string))
key-fn nil array-coerce-fn))))
(defn parse-stream
"Returns the Clojure object corresponding to the given reader, reader must
implement BufferedReader. An optional key-fn argument can be either true (to
coerce keys to keywords),false to leave them as strings, or a function to
provide custom coercion.
The array-coerce-fn is an optional function taking the name of an array field,
and returning the collection to be used for array values.
If the top-level object is an array, it will be parsed lazily (use
`parse-strict' if strict parsing is required for top-level arrays.
If multiple objects (enclosed in a top-level `{}' need to be parsed lazily,
see parsed-seq."
([rdr] (parse-stream rdr nil nil))
([rdr key-fn] (parse-stream rdr key-fn nil))
([^BufferedReader rdr key-fn array-coerce-fn]
(when rdr
(parse/parse
(.createParser ^JsonFactory (or factory/*json-factory*
factory/json-factory)
^Reader rdr)
key-fn nil array-coerce-fn))))
(defn parse-smile
"Returns the Clojure object corresponding to the given SMILE-encoded bytes.
An optional key-fn argument can be either true (to coerce keys to keywords),
false to leave them as strings, or a function to provide custom coercion.
The array-coerce-fn is an optional function taking the name of an array field,
and returning the collection to be used for array values."
([bytes] (parse-smile bytes nil nil))
([bytes key-fn] (parse-smile bytes key-fn nil))
([^bytes bytes key-fn array-coerce-fn]
(when bytes
(parse/parse
(.createParser ^SmileFactory (or factory/*smile-factory*
factory/smile-factory) bytes)
key-fn nil array-coerce-fn))))
(defn parse-cbor
"Returns the Clojure object corresponding to the given CBOR-encoded bytes.
An optional key-fn argument can be either true (to coerce keys to keywords),
false to leave them as strings, or a function to provide custom coercion.
The array-coerce-fn is an optional function taking the name of an array field,
and returning the collection to be used for array values."
([bytes] (parse-cbor bytes nil nil))
([bytes key-fn] (parse-cbor bytes key-fn nil))
([^bytes bytes key-fn array-coerce-fn]
(when bytes
(parse/parse
(.createParser ^CBORFactory (or factory/*cbor-factory*
factory/cbor-factory) bytes)
key-fn nil array-coerce-fn))))
(def ^{:doc "Object used to determine end of lazy parsing attempt."}
eof (Object.))
;; Lazy parsers
(defn- parsed-seq*
"Internal lazy-seq parser"
[^JsonParser parser key-fn array-coerce-fn]
(lazy-seq
(let [elem (parse/parse-strict parser key-fn eof array-coerce-fn)]
(when-not (identical? elem eof)
(cons elem (parsed-seq* parser key-fn array-coerce-fn))))))
(defn parsed-seq
"Returns a lazy seq of Clojure objects corresponding to the JSON read from
the given reader. The seq continues until the end of the reader is reached.
The array-coerce-fn is an optional function taking the name of an array field,
and returning the collection to be used for array values.
If non-laziness is needed, see parse-stream."
([reader] (parsed-seq reader nil nil))
([reader key-fn] (parsed-seq reader key-fn nil))
([^BufferedReader reader key-fn array-coerce-fn]
(when reader
(parsed-seq* (.createParser ^JsonFactory
(or factory/*json-factory*
factory/json-factory)
^Reader reader)
key-fn array-coerce-fn))))
(defn parsed-smile-seq
"Returns a lazy seq of Clojure objects corresponding to the SMILE read from
the given reader. The seq continues until the end of the reader is reached.
The array-coerce-fn is an optional function taking the name of an array field,
and returning the collection to be used for array values."
([reader] (parsed-smile-seq reader nil nil))
([reader key-fn] (parsed-smile-seq reader key-fn nil))
([^BufferedReader reader key-fn array-coerce-fn]
(when reader
(parsed-seq* (.createParser ^SmileFactory
(or factory/*smile-factory*
factory/smile-factory)
^Reader reader)
key-fn array-coerce-fn))))
;; aliases for clojure-json users
(defmacro copy-arglists
[dst src]
`(alter-meta! (var ~dst) merge (select-keys (meta (var ~src)) [:arglists])))
(def encode "Alias to generate-string for clojure-json users" generate-string)
(copy-arglists encode generate-string)
(def encode-stream "Alias to generate-stream for clojure-json users" generate-stream)
(copy-arglists encode-stream generate-stream)
(def encode-smile "Alias to generate-smile for clojure-json users" generate-smile)
(copy-arglists encode-smile generate-smile)
(def decode "Alias to parse-string for clojure-json users" parse-string)
(copy-arglists decode parse-string)
(def decode-strict "Alias to parse-string-strict for clojure-json users" parse-string-strict)
(copy-arglists decode-strict parse-string-strict)
(def decode-stream "Alias to parse-stream for clojure-json users" parse-stream)
(copy-arglists decode-stream parse-stream)
(def decode-smile "Alias to parse-smile for clojure-json users" parse-smile)
(copy-arglists decode-smile parse-smile)
cheshire-5.7.1/src/cheshire/custom.clj 0000664 0000000 0000000 00000022243 13076023672 0017714 0 ustar 00root root 0000000 0000000 (ns cheshire.custom
"DEPRECATED
Methods used for extending JSON generation to different Java classes.
Has the same public API as core.clj so they can be swapped in and out."
(:use [cheshire.factory])
(:require [cheshire.core :as core]
[cheshire.generate :as generate])
(:import (java.io BufferedWriter ByteArrayOutputStream StringWriter)
(java.util Date SimpleTimeZone)
(java.text SimpleDateFormat)
(java.sql Timestamp)
(com.fasterxml.jackson.dataformat.smile SmileFactory)
(com.fasterxml.jackson.core JsonFactory JsonGenerator
JsonGenerator$Feature
JsonGenerationException JsonParser)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;; DEPRECATED, DO NOT USE ;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; date format rebound for custom encoding
(def ^{:dynamic true :private true} *date-format*)
;; pre-allocated exception for fast-failing core attempt for custom encoding
(def ^{:private true} core-failure (JsonGenerationException.
"Cannot custom JSON encode object"))
(defprotocol JSONable
(to-json [t jg]))
(defn encode*
(^String [obj]
(encode* obj nil))
(^String [obj opt-map]
(binding [*date-format* (or (:date-format opt-map) default-date-format)]
(let [sw (StringWriter.)
generator (.createJsonGenerator
^JsonFactory (or *json-factory* json-factory) sw)]
(when (:pretty opt-map)
(.useDefaultPrettyPrinter generator))
(when (:escape-non-ascii opt-map)
(.enable generator JsonGenerator$Feature/ESCAPE_NON_ASCII))
(if obj
(to-json obj generator)
(.writeNull generator))
(.flush generator)
(.toString sw)))))
(def encode encode*)
(core/copy-arglists encode encode*)
(defn encode-stream*
(^String [obj ^BufferedWriter w]
(encode-stream* obj w nil))
(^String [obj ^BufferedWriter w opt-map]
(binding [*date-format* (or (:date-format opt-map) default-date-format)]
(let [generator (.createJsonGenerator
^JsonFactory (or *json-factory* json-factory) w)]
(when (:pretty opt-map)
(.useDefaultPrettyPrinter generator))
(when (:escape-non-ascii opt-map)
(.enable generator JsonGenerator$Feature/ESCAPE_NON_ASCII))
(to-json obj generator)
(.flush generator)
w))))
(def encode-stream encode-stream*)
(core/copy-arglists encode-stream encode-stream*)
(defn encode-smile*
(^bytes [obj]
(encode-smile* obj nil))
(^bytes [obj opt-map]
(binding [*date-format* (or (:date-format opt-map) default-date-format)]
(let [baos (ByteArrayOutputStream.)
generator (.createJsonGenerator ^SmileFactory
(or *smile-factory* smile-factory)
baos)]
(to-json obj generator)
(.flush generator)
(.toByteArray baos)))))
(def encode-smile encode-smile*)
(core/copy-arglists encode-smile encode-smile*)
;; there are no differences in parsing, but these are here to make
;; this a self-contained namespace if desired
(def parse core/decode)
(core/copy-arglists parse core/decode)
(def parse-string core/decode)
(core/copy-arglists parse-string core/decode)
(def parse-stream core/decode-stream)
(core/copy-arglists parse-stream core/decode-stream)
(def parse-smile core/decode-smile)
(core/copy-arglists parse-smile core/decode-smile)
(def parsed-seq core/parsed-seq)
(core/copy-arglists parsed-seq core/parsed-seq)
(def decode core/parse-string)
(core/copy-arglists decode core/parse-string)
(def decode-stream parse-stream)
(core/copy-arglists decode-stream core/parse-stream)
(def decode-smile parse-smile)
(core/copy-arglists decode-smile core/parse-smile)
;; aliases for encoding
(def generate-string encode*)
(core/copy-arglists generate-string encode*)
(def generate-string* encode*)
(core/copy-arglists generate-string* encode*)
(def generate-stream encode-stream*)
(core/copy-arglists generate-stream encode-stream*)
(def generate-stream* encode-stream*)
(core/copy-arglists generate-stream* encode-stream*)
(def generate-smile encode-smile*)
(core/copy-arglists generate-smile encode-smile*)
(def generate-smile* encode-smile*)
(core/copy-arglists generate-smile* encode-smile*)
;; Generic encoders, these can be used by someone writing a custom
;; encoder if so desired, after transforming an arbitrary data
;; structure into a clojure one, these can just be called.
(defn encode-nil
"Encode null to the json generator."
[_ ^JsonGenerator jg]
(.writeNull jg))
(defn encode-str
"Encode a string to the json generator."
[^String s ^JsonGenerator jg]
(.writeString jg (str s)))
(defn encode-number
"Encode anything implementing java.lang.Number to the json generator."
[^java.lang.Number n ^JsonGenerator jg]
(generate/encode-number n jg))
(defn encode-long
"Encode anything implementing java.lang.Number to the json generator."
[^Long n ^JsonGenerator jg]
(.writeNumber jg (long n)))
(defn encode-int
"Encode anything implementing java.lang.Number to the json generator."
[n ^JsonGenerator jg]
(.writeNumber jg (long n)))
(defn encode-ratio
"Encode a clojure.lang.Ratio to the json generator."
[^clojure.lang.Ratio n ^JsonGenerator jg]
(.writeNumber jg (double n)))
(defn encode-seq
"Encode a seq to the json generator."
[s ^JsonGenerator jg]
(.writeStartArray jg)
(doseq [i s]
(to-json i jg))
(.writeEndArray jg))
(defn encode-date
"Encode a date object to the json generator."
[^Date d ^JsonGenerator jg]
(let [sdf (SimpleDateFormat. *date-format*)]
(.setTimeZone sdf (SimpleTimeZone. 0 "UTC"))
(.writeString jg (.format sdf d))))
(defn encode-bool
"Encode a Boolean object to the json generator."
[^Boolean b ^JsonGenerator jg]
(.writeBoolean jg b))
(defn encode-named
"Encode a keyword to the json generator."
[^clojure.lang.Keyword k ^JsonGenerator jg]
(.writeString jg (if-let [ns (namespace k)]
(str ns "/" (name k))
(name k))))
(defn encode-map
"Encode a clojure map to the json generator."
[^clojure.lang.IPersistentMap m ^JsonGenerator jg]
(.writeStartObject jg)
(doseq [[k v] m]
(.writeFieldName jg (if (instance? clojure.lang.Keyword k)
(if-let [ns (namespace k)]
(str ns "/" (name k))
(name k))
(str k)))
(to-json v jg))
(.writeEndObject jg))
(defn encode-symbol
"Encode a clojure symbol to the json generator."
[^clojure.lang.Symbol s ^JsonGenerator jg]
(.writeString jg (str s)))
;; extended implementations for clojure datastructures
(extend nil
JSONable
{:to-json encode-nil})
(extend java.lang.String
JSONable
{:to-json encode-str})
;; This is lame, thanks for changing all the BigIntegers to BigInts
;; in 1.3 clojure/core :-/
(defmacro handle-bigint []
(when (not= {:major 1 :minor 2} (select-keys *clojure-version*
[:major :minor]))
`(extend clojure.lang.BigInt
JSONable
{:to-json ~'(fn encode-bigint
[^clojure.lang.BigInt n ^JsonGenerator jg]
(.writeNumber jg (.toBigInteger n)))})))
(handle-bigint)
(extend clojure.lang.Ratio
JSONable
{:to-json encode-ratio})
(extend Long
JSONable
{:to-json encode-long})
(extend Short
JSONable
{:to-json encode-int})
(extend Byte
JSONable
{:to-json encode-int})
(extend java.lang.Number
JSONable
{:to-json encode-number})
(extend clojure.lang.ISeq
JSONable
{:to-json encode-seq})
(extend clojure.lang.IPersistentVector
JSONable
{:to-json encode-seq})
(extend clojure.lang.IPersistentSet
JSONable
{:to-json encode-seq})
(extend clojure.lang.IPersistentList
JSONable
{:to-json encode-seq})
(extend java.util.Date
JSONable
{:to-json encode-date})
(extend java.sql.Timestamp
JSONable
{:to-json #(encode-date (Date. (.getTime ^java.sql.Timestamp %1)) %2)})
(extend java.util.UUID
JSONable
{:to-json encode-str})
(extend java.lang.Boolean
JSONable
{:to-json encode-bool})
(extend clojure.lang.Keyword
JSONable
{:to-json encode-named})
(extend clojure.lang.IPersistentMap
JSONable
{:to-json encode-map})
(extend clojure.lang.Symbol
JSONable
{:to-json encode-symbol})
(extend clojure.lang.Associative
JSONable
{:to-json encode-map})
(extend java.util.Map
JSONable
{:to-json encode-map})
(extend java.util.Set
JSONable
{:to-json encode-seq})
(extend java.util.List
JSONable
{:to-json encode-seq})
;; Utility methods to add and remove encoders
(defn add-encoder
"Provide an encoder for a type not handled by Cheshire.
ex. (add-encoder java.net.URL encode-string)
See encode-str, encode-map, etc, in the cheshire.custom
namespace for encoder examples."
[cls encoder]
(extend cls
JSONable
{:to-json encoder}))
(defn remove-encoder
"Remove encoder for a given type.
ex. (remove-encoder java.net.URL)"
[cls]
(alter-var-root #'JSONable #(assoc % :impls (dissoc (:impls %) cls)))
(clojure.core/-reset-methods JSONable))
cheshire-5.7.1/src/cheshire/experimental.clj 0000664 0000000 0000000 00000002506 13076023672 0021077 0 ustar 00root root 0000000 0000000 (ns cheshire.experimental
"Experimental JSON encoding/decoding tools."
(:require [cheshire.core :refer :all]
[clojure.java.io :refer :all]
[tigris.core :refer [str-escaping-input-stream]])
(:import (java.io ByteArrayInputStream SequenceInputStream)))
(defn encode-large-field-in-map
"EXPERIMENTAL - SUBJECT TO CHANGE.
Given a clojure object, a field name and a stream for a the string value of
the field, return a stream that, when read, JSON encodes in a streamy way.
An optional opt-map can be specified to pass enocding options to the map
encoding, supports the same options as generate-string.
Note that the input stream is not closed. You are responsible for closing it
by calling .close() on the stream object returned from this method."
([obj field stream]
(encode-large-field-in-map obj field stream nil))
([obj field stream & [opt-map]]
(let [otherstr (encode (dissoc obj field) opt-map)
truncstr (str (subs otherstr 0 (dec (count otherstr))))
stream (str-escaping-input-stream stream)
pre-stream (ByteArrayInputStream.
(.getBytes (str truncstr ",\"" (name field) "\":\"")))
post-stream (ByteArrayInputStream. (.getBytes "\"}"))]
(reduce #(SequenceInputStream. %1 %2) [pre-stream stream post-stream]))))
cheshire-5.7.1/src/cheshire/factory.clj 0000664 0000000 0000000 00000012642 13076023672 0020053 0 ustar 00root root 0000000 0000000 (ns cheshire.factory
"Factories used for JSON/SMILE generation, used by both the core and
custom generators."
(:import (com.fasterxml.jackson.dataformat.smile SmileFactory)
(com.fasterxml.jackson.dataformat.cbor CBORFactory)
(com.fasterxml.jackson.core JsonFactory JsonFactory$Feature
JsonParser$Feature)))
;; default date format used to JSON-encode Date objects
(def default-date-format "yyyy-MM-dd'T'HH:mm:ss'Z'")
(defonce default-factory-options
{:auto-close-source false
:allow-comments false
:allow-unquoted-field-names false
:allow-single-quotes false
:allow-unquoted-control-chars true
:allow-backslash-escaping false
:allow-numeric-leading-zeros false
:allow-non-numeric-numbers false
:intern-field-names false
:canonicalize-field-names false})
;; Factory objects that are needed to do the encoding and decoding
(defn make-json-factory
^JsonFactory [opts]
(let [opts (merge default-factory-options opts)]
(doto (JsonFactory.)
(.configure JsonParser$Feature/AUTO_CLOSE_SOURCE
(boolean (:auto-close-source opts)))
(.configure JsonParser$Feature/ALLOW_COMMENTS
(boolean (:allow-comments opts)))
(.configure JsonParser$Feature/ALLOW_UNQUOTED_FIELD_NAMES
(boolean (:allow-unquoted-field-names opts)))
(.configure JsonParser$Feature/ALLOW_SINGLE_QUOTES
(boolean (:allow-single-quotes opts)))
(.configure JsonParser$Feature/ALLOW_UNQUOTED_CONTROL_CHARS
(boolean (:allow-unquoted-control-chars opts)))
(.configure JsonParser$Feature/ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER
(boolean (:allow-backslash-escaping opts)))
(.configure JsonParser$Feature/ALLOW_NUMERIC_LEADING_ZEROS
(boolean (:allow-numeric-leading-zeros opts)))
(.configure JsonParser$Feature/ALLOW_NON_NUMERIC_NUMBERS
(boolean (:allow-non-numeric-numbers opts)))
(.configure JsonFactory$Feature/INTERN_FIELD_NAMES
(boolean (:intern-field-names opts)))
(.configure JsonFactory$Feature/CANONICALIZE_FIELD_NAMES
(boolean (:canonicalize-field-names opts))))))
(defn make-smile-factory
^SmileFactory [opts]
(let [opts (merge default-factory-options opts)]
(doto (SmileFactory.)
(.configure JsonParser$Feature/AUTO_CLOSE_SOURCE
(boolean (:auto-close-source opts)))
(.configure JsonParser$Feature/ALLOW_COMMENTS
(boolean (:allow-comments opts)))
(.configure JsonParser$Feature/ALLOW_UNQUOTED_FIELD_NAMES
(boolean (:allow-unquoted-field-names opts)))
(.configure JsonParser$Feature/ALLOW_SINGLE_QUOTES
(boolean (:allow-single-quotes opts)))
(.configure JsonParser$Feature/ALLOW_UNQUOTED_CONTROL_CHARS
(boolean (:allow-unquoted-control-chars opts)))
(.configure JsonParser$Feature/ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER
(boolean (:allow-backslash-escaping opts)))
(.configure JsonParser$Feature/ALLOW_NUMERIC_LEADING_ZEROS
(boolean (:allow-numeric-leading-zeros opts)))
(.configure JsonParser$Feature/ALLOW_NON_NUMERIC_NUMBERS
(boolean (:allow-non-numeric-numbers opts)))
(.configure JsonFactory$Feature/INTERN_FIELD_NAMES
(boolean (:intern-field-names opts)))
(.configure JsonFactory$Feature/CANONICALIZE_FIELD_NAMES
(boolean (:canonicalize-field-names opts))))))
(defn make-cbor-factory
^CBORFactory [opts]
(let [opts (merge default-factory-options opts)]
(doto (CBORFactory.)
(.configure JsonParser$Feature/AUTO_CLOSE_SOURCE
(boolean (:auto-close-source opts)))
(.configure JsonParser$Feature/ALLOW_COMMENTS
(boolean (:allow-comments opts)))
(.configure JsonParser$Feature/ALLOW_UNQUOTED_FIELD_NAMES
(boolean (:allow-unquoted-field-names opts)))
(.configure JsonParser$Feature/ALLOW_SINGLE_QUOTES
(boolean (:allow-single-quotes opts)))
(.configure JsonParser$Feature/ALLOW_UNQUOTED_CONTROL_CHARS
(boolean (:allow-unquoted-control-chars opts)))
(.configure JsonParser$Feature/ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER
(boolean (:allow-backslash-escaping opts)))
(.configure JsonParser$Feature/ALLOW_NUMERIC_LEADING_ZEROS
(boolean (:allow-numeric-leading-zeros opts)))
(.configure JsonParser$Feature/ALLOW_NON_NUMERIC_NUMBERS
(boolean (:allow-non-numeric-numbers opts)))
(.configure JsonFactory$Feature/INTERN_FIELD_NAMES
(boolean (:intern-field-names opts)))
(.configure JsonFactory$Feature/CANONICALIZE_FIELD_NAMES
(boolean (:canonicalize-field-names opts))))))
(defonce ^JsonFactory json-factory (make-json-factory default-factory-options))
(defonce ^SmileFactory smile-factory
(make-smile-factory default-factory-options))
(defonce ^CBORFactory cbor-factory (make-cbor-factory default-factory-options))
;; dynamically rebindable json factory, if desired
(def ^{:dynamic true :tag JsonFactory} *json-factory* nil)
;; dynamically rebindable smile factory, if desired
(def ^{:dynamic true :tag SmileFactory} *smile-factory* nil)
;; dynamically rebindable cbor factory, if desired
(def ^{:dynamic true :tag CBORFactory} *cbor-factory* nil)
cheshire-5.7.1/src/cheshire/generate.clj 0000664 0000000 0000000 00000021371 13076023672 0020175 0 ustar 00root root 0000000 0000000 (ns cheshire.generate
"Namespace used to generate JSON from Clojure data structures."
(:import (com.fasterxml.jackson.core JsonGenerator JsonGenerationException)
(java.util Date Map List Set SimpleTimeZone UUID)
(java.sql Timestamp)
(java.text SimpleDateFormat)
(java.math BigInteger)
(clojure.lang IPersistentCollection Keyword Ratio Symbol)))
;; date format rebound for custom encoding
(def ^{:dynamic true :private true} *date-format*)
(defmacro tag
([obj]
`(vary-meta ~obj assoc :tag `JsonGenerator)))
(defprotocol JSONable
(to-json [t jg]))
(definline write-string [^JsonGenerator jg ^String str]
`(.writeString ~(tag jg) ~str))
(defmacro fail [obj jg ^Exception e]
`(try
(to-json ~obj ~jg)
(catch IllegalArgumentException _#
(throw (or ~e (JsonGenerationException.
(str "Cannot JSON encode object of class: "
(class ~obj) ": " ~obj)))))))
(defmacro number-dispatch [jg obj e]
(let [g (tag (gensym 'jg))
o (gensym 'obj)
common-clauses `[Integer (.writeNumber ~g (int ~o))
Long (.writeNumber ~g (long ~o))
Double (.writeNumber ~g (double ~o))
Float (.writeNumber ~g (float ~o))
BigInteger (.writeNumber
~g ~(with-meta o {:tag `BigInteger}))
BigDecimal (.writeNumber
~g ~(with-meta o {:tag `BigDecimal}))
Ratio (.writeNumber ~g (double ~o))
Short (.writeNumber ~g (int ~o))
Byte (.writeNumber ~g (int ~o))]]
`(let [~g ~jg
~o ~obj]
(condp instance? ~o
~@(if (< 2 (:minor *clojure-version*))
`[~@common-clauses
clojure.lang.BigInt (.writeNumber
~g (.toBigInteger
~(vary-meta obj assoc :tag
`clojure.lang.BigInt)))]
common-clauses)
(fail ~o ~g ~e)))))
(declare generate)
(definline generate-basic-map
[^JsonGenerator jg obj ^String date-format ^Exception e]
(let [jg (tag jg)]
`(do
(.writeStartObject ~jg)
(doseq [m# ~obj]
(let [k# (key m#)
v# (val m#)]
(.writeFieldName ~jg (if (keyword? k#)
(.substring (str k#) 1)
(str k#)))
(generate ~jg v# ~date-format ~e nil)))
(.writeEndObject ~jg))))
(definline generate-key-fn-map
[^JsonGenerator jg obj ^String date-format ^Exception e key-fn]
(let [k (gensym 'k)
name (gensym 'name)
jg (tag jg)]
`(do
(.writeStartObject ~jg)
(doseq [m# ~obj]
(let [~k (key m#)
v# (val m#)
^String name# (if (keyword? ~k)
(~key-fn ~k)
(str ~k))]
(.writeFieldName ~jg name#)
(generate ~jg v# ~date-format ~e ~key-fn)))
(.writeEndObject ~jg))))
(definline generate-map
[^JsonGenerator jg obj ^String date-format ^Exception e key-fn]
`(if (nil? ~key-fn)
(generate-basic-map ~jg ~obj ~date-format ~e)
(generate-key-fn-map ~jg ~obj ~date-format ~e ~key-fn)))
(definline generate-array [^JsonGenerator jg obj ^String date-format
^Exception e key-fn]
(let [jg (tag jg)]
`(do
(.writeStartArray ~jg)
(doseq [item# ~obj]
(generate ~jg item# ~date-format ~e ~key-fn))
(.writeEndArray ~jg))))
(defmacro i?
"Just to shorten 'instance?' and for debugging."
[k obj]
;;(println :inst? k obj)
`(instance? ~k ~obj))
(defn byte-array? [o]
(let [c (class o)]
(and (.isArray c)
(identical? (.getComponentType c) Byte/TYPE))))
(defn generate [^JsonGenerator jg obj ^String date-format ^Exception ex key-fn]
(cond
(nil? obj) (.writeNull ^JsonGenerator jg)
(get (:impls JSONable) (class obj)) (#'to-json obj jg)
(i? clojure.lang.IPersistentMap obj)
(generate-map jg obj date-format ex key-fn)
(i? clojure.lang.IPersistentVector obj)
(generate-array jg obj date-format ex key-fn)
(i? clojure.lang.IPersistentSet obj)
(generate-array jg obj date-format ex key-fn)
(i? clojure.lang.IPersistentList obj)
(generate-array jg obj date-format ex key-fn)
(i? clojure.lang.ISeq obj)
(generate-array jg obj date-format ex key-fn)
(i? clojure.lang.Associative obj)
(generate-map jg obj date-format ex key-fn)
(i? Number obj) (number-dispatch ^JsonGenerator jg obj ex)
(i? Boolean obj) (.writeBoolean ^JsonGenerator jg ^Boolean obj)
(i? String obj) (write-string ^JsonGenerator jg ^String obj)
(i? Character obj) (write-string ^JsonGenerator jg ^String (str obj))
(i? Keyword obj) (write-string ^JsonGenerator jg (.substring (str obj) 1))
(i? Map obj) (generate-map jg obj date-format ex key-fn)
(i? List obj) (generate-array jg obj date-format ex key-fn)
(i? Set obj) (generate-array jg obj date-format ex key-fn)
(byte-array? obj) (.writeBinary ^JsonGenerator jg ^bytes obj)
(i? UUID obj) (write-string ^JsonGenerator jg (.toString ^UUID obj))
(i? Symbol obj) (write-string ^JsonGenerator jg (.toString ^Symbol obj))
(i? Date obj) (let [sdf (doto (SimpleDateFormat. date-format)
(.setTimeZone (SimpleTimeZone. 0 "UTC")))]
(write-string ^JsonGenerator jg (.format sdf obj)))
(i? Timestamp obj) (let [date (Date. (.getTime ^Timestamp obj))
sdf (doto (SimpleDateFormat. date-format)
(.setTimeZone (SimpleTimeZone. 0 "UTC")))]
(write-string ^JsonGenerator jg (.format sdf obj)))
:else (fail obj jg ex)))
;; Generic encoders, these can be used by someone writing a custom
;; encoder if so desired, after transforming an arbitrary data
;; structure into a clojure one, these can just be called.
(defn encode-nil
"Encode null to the json generator."
[_ ^JsonGenerator jg]
(.writeNull jg))
(defn encode-str
"Encode a string to the json generator."
[^String s ^JsonGenerator jg]
(.writeString jg (str s)))
(defn encode-number
"Encode anything implementing java.lang.Number to the json generator."
[^java.lang.Number n ^JsonGenerator jg]
(number-dispatch jg n nil))
(defn encode-long
"Encode anything implementing java.lang.Number to the json generator."
[^Long n ^JsonGenerator jg]
(.writeNumber jg (long n)))
(defn encode-int
"Encode anything implementing java.lang.Number to the json generator."
[n ^JsonGenerator jg]
(.writeNumber jg (long n)))
(defn encode-ratio
"Encode a clojure.lang.Ratio to the json generator."
[^clojure.lang.Ratio n ^JsonGenerator jg]
(.writeNumber jg (double n)))
(defn encode-seq
"Encode a seq to the json generator."
[s ^JsonGenerator jg]
(.writeStartArray jg)
(doseq [i s]
(generate jg i *date-format* nil nil))
(.writeEndArray jg))
(defn encode-date
"Encode a date object to the json generator."
[^Date d ^JsonGenerator jg]
(let [sdf (SimpleDateFormat. *date-format*)]
(.setTimeZone sdf (SimpleTimeZone. 0 "UTC"))
(.writeString jg (.format sdf d))))
(defn encode-bool
"Encode a Boolean object to the json generator."
[^Boolean b ^JsonGenerator jg]
(.writeBoolean jg b))
(defn encode-named
"Encode a keyword to the json generator."
[^clojure.lang.Keyword k ^JsonGenerator jg]
(.writeString jg (if-let [ns (namespace k)]
(str ns "/" (name k))
(name k))))
(defn encode-map
"Encode a clojure map to the json generator."
[^clojure.lang.IPersistentMap m ^JsonGenerator jg]
(.writeStartObject jg)
(doseq [[k v] m]
(.writeFieldName jg (if (instance? clojure.lang.Keyword k)
(if-let [ns (namespace k)]
(str ns "/" (name k))
(name k))
(str k)))
(generate jg v *date-format* nil nil))
(.writeEndObject jg))
(defn encode-symbol
"Encode a clojure symbol to the json generator."
[^clojure.lang.Symbol s ^JsonGenerator jg]
(.writeString jg (str s)))
;; Utility methods to add and remove encoders
(defn add-encoder
"Provide an encoder for a type not handled by Cheshire.
ex. (add-encoder java.net.URL encode-string)
See encode-str, encode-map, etc, in the cheshire.custom
namespace for encoder examples."
[cls encoder]
(extend cls
JSONable
{:to-json encoder}))
(defn remove-encoder
"Remove encoder for a given type.
ex. (remove-encoder java.net.URL)"
[cls]
(alter-var-root #'JSONable #(assoc % :impls (dissoc (:impls %) cls)))
(clojure.core/-reset-methods JSONable))
cheshire-5.7.1/src/cheshire/generate_seq.clj 0000664 0000000 0000000 00000012521 13076023672 0021042 0 ustar 00root root 0000000 0000000 (ns cheshire.generate-seq
"Namespace used to generate JSON from Clojure data structures in a
sequential way."
(:use [cheshire.generate :only [tag JSONable to-json i?
number-dispatch write-string
fail]])
(:import (com.fasterxml.jackson.core JsonGenerator JsonGenerationException)
(java.util Date Map List Set SimpleTimeZone UUID)
(java.sql Timestamp)
(java.text SimpleDateFormat)
(java.math BigInteger)
(clojure.lang IPersistentCollection Keyword Ratio Symbol)))
(definline write-start-object [^JsonGenerator jg wholeness]
`(if (contains? #{:all :start :start-inner} ~wholeness)
(.writeStartObject ~jg)))
(definline write-end-object [^JsonGenerator jg wholeness]
`(if (contains? #{:all :end} ~wholeness)
(.writeEndObject ~jg)))
(definline write-start-array [^JsonGenerator jg wholeness]
`(if (contains? #{:all :start :start-inner} ~wholeness)
(.writeStartArray ~jg)))
(definline write-end-array [^JsonGenerator jg wholeness]
`(if (contains? #{:all :end} ~wholeness)
(.writeEndArray ~jg)))
(declare generate)
(definline generate-basic-map
[^JsonGenerator jg obj ^String date-format ^Exception e
wholeness]
(let [jg (tag jg)]
`(do
(write-start-object ~jg ~wholeness)
(doseq [m# ~obj]
(let [k# (key m#)
v# (val m#)]
(.writeFieldName ~jg (if (keyword? k#)
(.substring (str k#) 1)
(str k#)))
(generate ~jg v# ~date-format ~e nil
:wholeness (if (= ~wholeness :start-inner)
:start
:all))))
(write-end-object ~jg ~wholeness))))
(definline generate-key-fn-map
[^JsonGenerator jg obj ^String date-format ^Exception e
key-fn wholeness]
(let [k (gensym 'k)
name (gensym 'name)
jg (tag jg)]
`(do
(write-start-object ~jg ~wholeness)
(doseq [m# ~obj]
(let [~k (key m#)
v# (val m#)
^String name# (if (keyword? ~k)
(~key-fn ~k)
(str ~k))]
(.writeFieldName ~jg name#)
(generate ~jg v# ~date-format ~e ~key-fn
:wholeness (if (= ~wholeness :start-inner)
:start
:all))))
(write-end-object ~jg ~wholeness))))
(definline generate-map
[^JsonGenerator jg obj ^String date-format ^Exception e
key-fn wholeness]
`(if (nil? ~key-fn)
(generate-basic-map ~jg ~obj ~date-format ~e ~wholeness)
(generate-key-fn-map ~jg ~obj ~date-format ~e ~key-fn ~wholeness)))
(definline generate-array [^JsonGenerator jg obj ^String date-format
^Exception e key-fn wholeness]
(let [jg (tag jg)]
`(do
(write-start-array ~jg ~wholeness)
(doseq [item# ~obj]
(generate ~jg item# ~date-format ~e ~key-fn
:wholeness (if (= ~wholeness :start-inner)
:start
:all)))
(write-end-array ~jg ~wholeness))))
(defn generate [^JsonGenerator jg obj ^String date-format
^Exception ex key-fn & {:keys [wholeness]}]
(let [wholeness (or wholeness :all)]
(cond
(nil? obj) (.writeNull ^JsonGenerator jg)
(get (:impls JSONable) (class obj)) (#'to-json obj jg)
(i? IPersistentCollection obj)
(condp instance? obj
clojure.lang.IPersistentMap
(generate-map jg obj date-format ex key-fn wholeness)
clojure.lang.IPersistentVector
(generate-array jg obj date-format ex key-fn wholeness)
clojure.lang.IPersistentSet
(generate-array jg obj date-format ex key-fn wholeness)
clojure.lang.IPersistentList
(generate-array jg obj date-format ex key-fn wholeness)
clojure.lang.ISeq
(generate-array jg obj date-format ex key-fn wholeness)
clojure.lang.Associative
(generate-map jg obj date-format ex key-fn wholeness))
(i? Number obj) (number-dispatch ^JsonGenerator jg obj ex)
(i? Boolean obj) (.writeBoolean ^JsonGenerator jg ^Boolean obj)
(i? String obj) (write-string ^JsonGenerator jg ^String obj)
(i? Character obj) (write-string ^JsonGenerator jg ^String (str obj))
(i? Keyword obj) (write-string ^JsonGenerator jg (.substring (str obj) 1))
(i? Map obj) (generate-map jg obj date-format ex key-fn wholeness)
(i? List obj) (generate-array jg obj date-format ex key-fn wholeness)
(i? Set obj) (generate-array jg obj date-format ex key-fn wholeness)
(i? UUID obj) (write-string ^JsonGenerator jg (.toString ^UUID obj))
(i? Symbol obj) (write-string ^JsonGenerator jg (.toString ^Symbol obj))
(i? Date obj) (let [sdf (doto (SimpleDateFormat. date-format)
(.setTimeZone (SimpleTimeZone. 0 "UTC")))]
(write-string ^JsonGenerator jg (.format sdf obj)))
(i? Timestamp obj) (let [date (Date. (.getTime ^Timestamp obj))
sdf (doto (SimpleDateFormat. date-format)
(.setTimeZone (SimpleTimeZone. 0 "UTC")))]
(write-string ^JsonGenerator jg (.format sdf obj)))
:else (fail obj jg ex))))
cheshire-5.7.1/src/cheshire/parse.clj 0000664 0000000 0000000 00000007050 13076023672 0017513 0 ustar 00root root 0000000 0000000 (ns cheshire.parse
(:import (com.fasterxml.jackson.core JsonParser JsonToken)))
(declare parse*)
(def ^{:doc "Flag to determine whether float values should be returned as
BigDecimals to retain precision. Defaults to false."
:dynamic true}
*use-bigdecimals?* false)
(defmacro ^:private tag
([obj]
`(vary-meta ~obj assoc :tag `JsonParser)))
(definline parse-object [^JsonParser jp key-fn bd? array-coerce-fn]
(let [jp (tag jp)]
`(do
(.nextToken ~jp)
(loop [mmap# (transient {})]
(if-not (identical? (.getCurrentToken ~jp)
JsonToken/END_OBJECT)
(let [key-str# (.getText ~jp)
_# (.nextToken ~jp)
key# (~key-fn key-str#)
mmap# (assoc! mmap# key#
(parse* ~jp ~key-fn ~bd? ~array-coerce-fn))]
(.nextToken ~jp)
(recur mmap#))
(persistent! mmap#))))))
(definline parse-array [^JsonParser jp key-fn bd? array-coerce-fn]
(let [jp (tag jp)]
`(let [array-field-name# (.getCurrentName ~jp)]
(.nextToken ~jp)
(loop [coll# (transient (if ~array-coerce-fn
(~array-coerce-fn array-field-name#)
[]))]
(if-not (identical? (.getCurrentToken ~jp)
JsonToken/END_ARRAY)
(let [coll# (conj! coll#
(parse* ~jp ~key-fn ~bd? ~array-coerce-fn))]
(.nextToken ~jp)
(recur coll#))
(persistent! coll#))))))
(defn lazily-parse-array [^JsonParser jp key-fn bd? array-coerce-fn]
(lazy-seq
(loop [chunk-idx 0, buf (chunk-buffer 32)]
(if (identical? (.getCurrentToken jp) JsonToken/END_ARRAY)
(chunk-cons (chunk buf) nil)
(do
(chunk-append buf (parse* jp key-fn bd? array-coerce-fn))
(.nextToken jp)
(let [chunk-idx* (unchecked-inc chunk-idx)]
(if (< chunk-idx* 32)
(recur chunk-idx* buf)
(chunk-cons
(chunk buf)
(lazily-parse-array jp key-fn bd? array-coerce-fn)))))))))
(defn parse* [^JsonParser jp key-fn bd? array-coerce-fn]
(condp identical? (.getCurrentToken jp)
JsonToken/START_OBJECT (parse-object jp key-fn bd? array-coerce-fn)
JsonToken/START_ARRAY (parse-array jp key-fn bd? array-coerce-fn)
JsonToken/VALUE_STRING (.getText jp)
JsonToken/VALUE_NUMBER_INT (.getNumberValue jp)
JsonToken/VALUE_NUMBER_FLOAT (if bd?
(.getDecimalValue jp)
(.getNumberValue jp))
JsonToken/VALUE_EMBEDDED_OBJECT (.getBinaryValue jp)
JsonToken/VALUE_TRUE true
JsonToken/VALUE_FALSE false
JsonToken/VALUE_NULL nil
(throw
(Exception.
(str "Cannot parse " (pr-str (.getCurrentToken jp)))))))
(defn parse-strict [^JsonParser jp key-fn eof array-coerce-fn]
(let [key-fn (or (if (identical? key-fn true) keyword key-fn) identity)]
(.nextToken jp)
(condp identical? (.getCurrentToken jp)
nil
eof
(parse* jp key-fn *use-bigdecimals?* array-coerce-fn))))
(defn parse [^JsonParser jp key-fn eof array-coerce-fn]
(let [key-fn (or (if (and (instance? Boolean key-fn) key-fn) keyword key-fn) identity)]
(.nextToken jp)
(condp identical? (.getCurrentToken jp)
nil
eof
JsonToken/START_ARRAY
(do
(.nextToken jp)
(lazily-parse-array jp key-fn *use-bigdecimals?* array-coerce-fn))
(parse* jp key-fn *use-bigdecimals?* array-coerce-fn))))
cheshire-5.7.1/src/java/ 0000775 0000000 0000000 00000000000 13076023672 0015034 5 ustar 00root root 0000000 0000000 cheshire-5.7.1/src/java/cheshire/ 0000775 0000000 0000000 00000000000 13076023672 0016626 5 ustar 00root root 0000000 0000000 cheshire-5.7.1/src/java/cheshire/prettyprint/ 0000775 0000000 0000000 00000000000 13076023672 0021232 5 ustar 00root root 0000000 0000000 cheshire-5.7.1/src/java/cheshire/prettyprint/CustomPrettyPrinter.java 0000664 0000000 0000000 00000004300 13076023672 0026120 0 ustar 00root root 0000000 0000000 package cheshire.prettyprint;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import java.io.IOException;
public class CustomPrettyPrinter extends DefaultPrettyPrinter {
private String _beforeArrayValues;
private String _afterArrayValues;
private String _objectFieldValueSeparator;
public CustomPrettyPrinter() {
super();
}
@Override
public void beforeArrayValues(JsonGenerator gen) throws IOException {
if (this._beforeArrayValues != null) {
gen.writeRaw(this._beforeArrayValues);
} else {
super.beforeArrayValues(gen);
}
}
@Override
public void writeEndArray(JsonGenerator gen, int nrOfValues) throws IOException {
if (this._afterArrayValues != null) {
gen.writeRaw(this._afterArrayValues + "]");
} else {
super.writeEndArray(gen, nrOfValues);
}
}
@Override
public void writeObjectFieldValueSeparator(JsonGenerator gen) throws IOException {
if (this._objectFieldValueSeparator != null) {
gen.writeRaw(this._objectFieldValueSeparator);
} else {
super.writeObjectFieldValueSeparator(gen);
}
}
public CustomPrettyPrinter setIndentation(String indentation, String lineBreak, boolean indentObjects, boolean indentArrays) {
Indenter indenter = new DefaultIndenter(indentation, lineBreak);
if (indentArrays) {
this.indentArraysWith(indenter);
}
if (indentObjects) {
this.indentObjectsWith(indenter);
}
return this;
}
public CustomPrettyPrinter setBeforeArrayValues(String beforeArrayValues) {
this._beforeArrayValues = beforeArrayValues;
return this;
}
public CustomPrettyPrinter setAfterArrayValues(String afterArrayValues) {
this._afterArrayValues = afterArrayValues;
return this;
}
public CustomPrettyPrinter setObjectFieldValueSeparator(String objectFieldValueSeparator) {
this._objectFieldValueSeparator = objectFieldValueSeparator;
return this;
}
}
cheshire-5.7.1/test/ 0000775 0000000 0000000 00000000000 13076023672 0014303 5 ustar 00root root 0000000 0000000 cheshire-5.7.1/test/all_month.geojson.gz 0000664 0000000 0000000 00002157335 13076023672 0020305 0 ustar 00root root 0000000 0000000 wjR all_month.geojson ̝[sFS}q<'c'qMmmm$$qEZ^Ѥ4@DDSM/BIF㇃[y}zȯ^_-϶uvX|U\%W|Ͳmvϫۼ6]TI
!\Wy.vޮ6n|f\fWb?UKon?ofRb1ygH&fg+-{sds-=7]k+~]dSsob0ls3\JHxX3_.vEZWUvD*sU3+Mg4goŶt6\./O?__~~fQ6""
X"[23\|fIsWW4|`WżOVH@쪘OL_(67r^\F;z)?/oYJ5*(~^ |m IzrD0 0 4WZ b Ŋ'c`ˬGV
0\U/'?|n&M'm߬a>
kFBwp1iN0K"E
o1:Nbz f~H0ncp_ssOkM~mLpt5jVj$jJճTNH$ UBT%b8cy0BJC]`::oZ
<