Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 428 lines (329 sloc) 19.799 kB
6248665 ready for use with limitations
Peter Ohler authored
1 # Oj gem
2 A fast JSON parser and Object marshaller as a Ruby gem.
3
4 ## <a name="installation">Installation</a>
5 gem install oj
6
7 ## <a name="source">Source</a>
8
9 *GitHub* *repo*: https://github.com/ohler55/oj
10
11 *RubyGems* *repo*: https://rubygems.org/gems/oj
12
13 ## <a name="build_status">Build Status</a>
14
da0330c getting the travis image to show status
Peter Ohler authored
15 [![Build Status](https://secure.travis-ci.org/ohler55/oj.png?branch=master)](http://travis-ci.org/ohler55/oj)
6248665 ready for use with limitations
Peter Ohler authored
16
17 ## <a name="links">Links of Interest</a>
18
e900e8e updated links and home page
Peter Ohler authored
19 [Need for Speed](http://www.ohler.com/dev/need_for_speed/need_for_speed.html) for an overview of how Oj::Doc was designed.
f5aae61 docs completed, ready for a release
Peter Ohler authored
20
afe4e99 changed json object format
Peter Ohler authored
21 *Fast XML parser and marshaller on RubyGems*: https://rubygems.org/gems/ox
6248665 ready for use with limitations
Peter Ohler authored
22
db33462 @MSNexploder fixed ox GitHub link
MSNexploder authored
23 *Fast XML parser and marshaller on GitHub*: https://github.com/ohler55/ox
57afd74 fixed a few bugs and added options
Peter Ohler authored
24
afe4e99 changed json object format
Peter Ohler authored
25 ## <a name="release">Release Notes</a>
6248665 ready for use with limitations
Peter Ohler authored
26
c9bb99f adding new encodings
Peter Ohler authored
27 ### Release 1.2.10
2444b99 pushing changes to readme that were lost in previous push
Peter Ohler authored
28
29 - Added check for circular on loading of circular dumped JSON.
30
c9bb99f adding new encodings
Peter Ohler authored
31 - Added support for direct serialization of BigDecimal, Date, and DateTime.
32
33 - Added json.rb to $" in mimic mode to avoid pulling in the real JSON by accident.
34
35 - Oj is now thread safe for all functions.
100b871 making timespec compatible
Peter Ohler authored
36
6248665 ready for use with limitations
Peter Ohler authored
37 ## <a name="description">Description</a>
38
39 Optimized JSON (Oj), as the name implies was written to provide speed
40 optimized JSON handling. It was designed as a faster alternative to Yajl and
41 other the common Ruby JSON parsers. So far is has achieved that at about 2
42 time faster than Yajl for parsing and 3 or more times faster writing JSON.
43
8711c85 serializes any Object now. Tests added as well.
Peter Ohler authored
44 Oj has several dump or serialization modes which control how Objects are
1a4aead @mat :effort parameter really is :mode.
mat authored
45 converted to JSON. These modes are set with the :mode option in either the
e0fb1d3 updatings docs and notes
Peter Ohler authored
46 default options or as one of the options to the dump() method.
47
48 - :strict mode will only allow the 7 basic JSON types to be serialized. Any other Object
49 will raise and Exception.
50
51 - :null mode replaces any Object that is not one of the JSON types is replaced by a JSON null.
52
53 - :object mode will dump any Object as a JSON Object with keys that match the
54 Ruby Object's variable names without the '@' character. This is the highest
55 performance mode.
56
57 - :compat mode is is the compatible with other systems. It will serialize any
58 Object but will check to see if the Object implements a to_hash() or to_json()
59 method. If either exists that method is used for serializing the Object. The
60 to_hash() is more flexible and produces more consistent output so it has a
61 preference over the to_json() method. If neither the to_json() or to_hash()
62 methods exist then the Oj internal Object variable encoding is used.
8711c85 serializes any Object now. Tests added as well.
Peter Ohler authored
63
d4a2c32 updated readme
Peter Ohler authored
64 Oj is compatible with Ruby 1.8.7, 1.9.2, 1.9.3, JRuby, RBX, and the latest 2.0dev.
65
66 Oj is also compatible with Rails. Just make sure the Oj gem is installed and
67 [multi_json](https://github.com/intridea/multi_json) will pick it up and use it.
5b248cc added Bag class and auto_define flag
Peter Ohler authored
68
6669206 ready for 0.6.0 release
Peter Ohler authored
69 ## <a name="compare">Comparisons</a>
70
f5aae61 docs completed, ready for a release
Peter Ohler authored
71 ### Fast Oj::Doc parser comparisons
72
73 The fast Oj::Doc parser is compared to the Yajl and JSON::Pure parsers with
74 strict JSON documents. No object conversions are included, just simple JSON.
75
76 Since the Oj::Doc deviation from the conventional parsers comparisons of not
77 only parsing but data access is also included. These tests use the
78 perf_fast.rb test file. The first benchmark is for just parsing. The second is
79 for doing a get on every leaf value in the JSON data structure. The third
80 fetchs a value from a specific spot in the document. With Yajl and JSON this
81 is done with a set of calls to fetch() for each level in the document. For
82 Oj::Doc a single fetch with a path is used.
83
84 The benchmark results are:
85
86 > perf_fast.rb -g 1 -f
87 --------------------------------------------------------------------------------
88 Parse Performance
89 Oj::Doc.parse 100000 times in 0.164 seconds or 609893.696 parse/sec.
90 Yajl.parse 100000 times in 3.168 seconds or 31569.902 parse/sec.
91 JSON::Ext.parse 100000 times in 3.282 seconds or 30464.826 parse/sec.
92
93 Summary:
94 System time (secs) rate (ops/sec)
95 --------- ----------- --------------
96 Oj::Doc 0.164 609893.696
97 Yajl 3.168 31569.902
98 JSON::Ext 3.282 30464.826
99
100 Comparison Matrix
101 (performance factor, 2.0 row is means twice as fast as column)
102 Oj::Doc Yajl JSON::Ext
103 --------- --------- --------- ---------
104 Oj::Doc 1.00 19.32 20.02
105 Yajl 0.05 1.00 1.04
106 JSON::Ext 0.05 0.96 1.00
107
108 --------------------------------------------------------------------------------
109 Parse and get all values Performance
110 Oj::Doc.parse 100000 times in 0.417 seconds or 240054.540 parse/sec.
111 Yajl.parse 100000 times in 5.159 seconds or 19384.191 parse/sec.
112 JSON::Ext.parse 100000 times in 5.269 seconds or 18978.638 parse/sec.
113
114 Summary:
115 System time (secs) rate (ops/sec)
116 --------- ----------- --------------
117 Oj::Doc 0.417 240054.540
118 Yajl 5.159 19384.191
119 JSON::Ext 5.269 18978.638
120
121 Comparison Matrix
122 (performance factor, 2.0 row is means twice as fast as column)
123 Oj::Doc Yajl JSON::Ext
124 --------- --------- --------- ---------
125 Oj::Doc 1.00 12.38 12.65
126 Yajl 0.08 1.00 1.02
127 JSON::Ext 0.08 0.98 1.00
128
129 --------------------------------------------------------------------------------
130 fetch nested Performance
131 Oj::Doc.fetch 100000 times in 0.094 seconds or 1059995.760 fetch/sec.
132 Ruby.fetch 100000 times in 0.503 seconds or 198851.434 fetch/sec.
133
134 Summary:
135 System time (secs) rate (ops/sec)
136 ------- ----------- --------------
137 Oj::Doc 0.094 1059995.760
138 Ruby 0.503 198851.434
139
140 Comparison Matrix
141 (performance factor, 2.0 row is means twice as fast as column)
142 Oj::Doc Ruby
143 ------- ------- -------
144 Oj::Doc 1.00 5.33
145 Ruby 0.19 1.00
146
147 What the results mean are that for getting just a few values from a JSON
148 document Oj::Doc is 20 times faster than any other parser and for accessing
149 all values it is still over 12 times faster than any other Ruby JSON parser.
150
151 ### Conventional Oj parser comparisons
152
6669206 ready for 0.6.0 release
Peter Ohler authored
153 The following table shows the difference is speeds between several
f5aae61 docs completed, ready for a release
Peter Ohler authored
154 serialization packages compared to the more conventional Oj parser. The tests
155 had to be scaled back due to limitation of some of the gems. I finally gave up
156 trying to get JSON Pure to serialize without errors with Ruby 1.9.3. It had
157 internal errors on anything other than a simple JSON structure. The errors
158 encountered were:
6669206 ready for 0.6.0 release
Peter Ohler authored
159
160 - MessagePack fails to convert Bignum to JSON
161
e0fb1d3 updatings docs and notes
Peter Ohler authored
162 - JSON Pure fails to serialize any numbers or Objects with the to_json() method
6669206 ready for 0.6.0 release
Peter Ohler authored
163
e0fb1d3 updatings docs and notes
Peter Ohler authored
164 Options were added to the test/perf_strict.rb test to run the test without
165 Object encoding and without Bignums.
6669206 ready for 0.6.0 release
Peter Ohler authored
166
167 None of the packages except Oj were able to serialize Ruby Objects that did
168 not have a to_json() method or were of the 7 native JSON types.
169
5b248cc added Bag class and auto_define flag
Peter Ohler authored
170 A perf_obj.rb file was added for comparing different Object marshalling
171 packages.
172
6669206 ready for 0.6.0 release
Peter Ohler authored
173 It is also worth noting that although Oj is slightly behind MessagePack for
174 parsing, Oj serialization is much faster than MessagePack even though Oj uses
175 human readable JSON vs the binary MessagePack format.
176
f5aae61 docs completed, ready for a release
Peter Ohler authored
177 Oj supports circular references when in :object mode and when the :circular
6b22c57 finishing off circular reference implementation
Peter Ohler authored
178 flag is true. None of the other gems tested supported circular
179 references. They failed in the following manners when the input included
180 circular references.
181
182 - Yajl core dumps Ruby
183
184 - JSON fails and raises an Exception
185
186 - MessagePack fails and raises an Exception
187
188 The benchmark results are:
6669206 ready for 0.6.0 release
Peter Ohler authored
189
190 with Object and Bignum encoding:
191
53e3bbc added benchmarks
Peter Ohler authored
192 > perf_strict.rb
6234873 ready for a release
Peter Ohler authored
193 --------------------------------------------------------------------------------
194 Load/Parse Performance
53e3bbc added benchmarks
Peter Ohler authored
195 Oj:compat.load 100000 times in 1.481 seconds or 67513.146 load/sec.
196 Oj.load 100000 times in 1.066 seconds or 93796.400 load/sec.
197 JSON::Ext.parse 100000 times in 3.023 seconds or 33074.875 parse/sec.
198 JSON::Pure.parse 100000 times in 18.908 seconds or 5288.799 parse/sec.
199 Ox.load 100000 times in 1.240 seconds or 80671.900 load/sec.
6234873 ready for a release
Peter Ohler authored
200
201 Summary:
202 System time (secs) rate (ops/sec)
203 ---------- ----------- --------------
53e3bbc added benchmarks
Peter Ohler authored
204 Oj 1.066 93796.400
205 Ox 1.240 80671.900
206 Oj:compat 1.481 67513.146
207 JSON::Ext 3.023 33074.875
208 JSON::Pure 18.908 5288.799
6234873 ready for a release
Peter Ohler authored
209
210 Comparison Matrix
211 (performance factor, 2.0 row is means twice as fast as column)
53e3bbc added benchmarks
Peter Ohler authored
212 Oj Ox Oj:compat JSON::Ext JSON::Pure
6234873 ready for a release
Peter Ohler authored
213 ---------- ---------- ---------- ---------- ---------- ----------
53e3bbc added benchmarks
Peter Ohler authored
214 Oj 1.00 1.16 1.39 2.84 17.73
215 Ox 0.86 1.00 1.19 2.44 15.25
216 Oj:compat 0.72 0.84 1.00 2.04 12.77
217 JSON::Ext 0.35 0.41 0.49 1.00 6.25
218 JSON::Pure 0.06 0.07 0.08 0.16 1.00
6234873 ready for a release
Peter Ohler authored
219
220
221 --------------------------------------------------------------------------------
222 Dump/Encode/Generate Performance
53e3bbc added benchmarks
Peter Ohler authored
223 Oj:compat.dump 100000 times in 0.789 seconds or 126715.249 dump/sec.
224 Oj.dump 100000 times in 0.457 seconds or 218798.751 dump/sec.
225 JSON::Ext.generate 100000 times in 4.371 seconds or 22878.630 generate/sec.
226 Ox.dump 100000 times in 0.501 seconds or 199425.256 dump/sec.
6234873 ready for a release
Peter Ohler authored
227
228 Summary:
229 System time (secs) rate (ops/sec)
230 --------- ----------- --------------
53e3bbc added benchmarks
Peter Ohler authored
231 Oj 0.457 218798.751
232 Ox 0.501 199425.256
233 Oj:compat 0.789 126715.249
234 JSON::Ext 4.371 22878.630
6234873 ready for a release
Peter Ohler authored
235
236 Comparison Matrix
237 (performance factor, 2.0 row is means twice as fast as column)
53e3bbc added benchmarks
Peter Ohler authored
238 Oj Ox Oj:compat JSON::Ext
6234873 ready for a release
Peter Ohler authored
239 --------- --------- --------- --------- ---------
53e3bbc added benchmarks
Peter Ohler authored
240 Oj 1.00 1.10 1.73 9.56
241 Ox 0.91 1.00 1.57 8.72
242 Oj:compat 0.58 0.64 1.00 5.54
243 JSON::Ext 0.10 0.11 0.18 1.00
244
245
246 The following packages were not included for the reason listed
247 ***** MessagePack: RangeError: bignum too big to convert into `unsigned long long'
248 ***** Yajl: RuntimeError: Yajl parse and encode did not return the same object as the original.
249 ***** JSON::Pure: TypeError: wrong argument type JSON::Pure::Generator::State (expected Data)
6669206 ready for 0.6.0 release
Peter Ohler authored
250
53e3bbc added benchmarks
Peter Ohler authored
251 without Objects or numbers (for JSON Pure, Yajl, and Messagepack) JSON:
6669206 ready for 0.6.0 release
Peter Ohler authored
252
6234873 ready for a release
Peter Ohler authored
253 --------------------------------------------------------------------------------
254 Load/Parse Performance
53e3bbc added benchmarks
Peter Ohler authored
255 Oj:compat.load 100000 times in 0.806 seconds or 124051.164 load/sec.
256 Oj.load 100000 times in 0.810 seconds or 123384.587 load/sec.
257 Yajl.parse 100000 times in 1.441 seconds or 69385.996 parse/sec.
258 JSON::Ext.parse 100000 times in 1.567 seconds or 63797.848 parse/sec.
259 JSON::Pure.parse 100000 times in 13.500 seconds or 7407.247 parse/sec.
260 Ox.load 100000 times in 0.954 seconds or 104836.748 load/sec.
261 MessagePack.unpack 100000 times in 0.651 seconds or 153707.817 unpack/sec.
6234873 ready for a release
Peter Ohler authored
262
263 Summary:
264 System time (secs) rate (ops/sec)
265 ----------- ----------- --------------
53e3bbc added benchmarks
Peter Ohler authored
266 MessagePack 0.651 153707.817
267 Oj:compat 0.806 124051.164
268 Oj 0.810 123384.587
269 Ox 0.954 104836.748
270 Yajl 1.441 69385.996
271 JSON::Ext 1.567 63797.848
272 JSON::Pure 13.500 7407.247
6234873 ready for a release
Peter Ohler authored
273
274 Comparison Matrix
275 (performance factor, 2.0 row is means twice as fast as column)
53e3bbc added benchmarks
Peter Ohler authored
276 MessagePack Oj:compat Oj Ox Yajl JSON::Ext JSON::Pure
277 ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
278 MessagePack 1.00 1.24 1.25 1.47 2.22 2.41 20.75
279 Oj:compat 0.81 1.00 1.01 1.18 1.79 1.94 16.75
280 Oj 0.80 0.99 1.00 1.18 1.78 1.93 16.66
281 Ox 0.68 0.85 0.85 1.00 1.51 1.64 14.15
282 Yajl 0.45 0.56 0.56 0.66 1.00 1.09 9.37
283 JSON::Ext 0.42 0.51 0.52 0.61 0.92 1.00 8.61
284 JSON::Pure 0.05 0.06 0.06 0.07 0.11 0.12 1.00
6234873 ready for a release
Peter Ohler authored
285
286
287 --------------------------------------------------------------------------------
288 Dump/Encode/Generate Performance
53e3bbc added benchmarks
Peter Ohler authored
289 Oj:compat.dump 100000 times in 0.173 seconds or 578526.262 dump/sec.
290 Oj.dump 100000 times in 0.179 seconds or 558362.880 dump/sec.
291 Yajl.encode 100000 times in 0.776 seconds or 128794.279 encode/sec.
292 JSON::Ext.generate 100000 times in 3.511 seconds or 28483.812 generate/sec.
293 JSON::Pure.generate 100000 times in 7.389 seconds or 13533.717 generate/sec.
294 Ox.dump 100000 times in 0.196 seconds or 510589.629 dump/sec.
295 MessagePack.pack 100000 times in 0.317 seconds or 315307.220 pack/sec.
6234873 ready for a release
Peter Ohler authored
296
297 Summary:
298 System time (secs) rate (ops/sec)
299 ----------- ----------- --------------
53e3bbc added benchmarks
Peter Ohler authored
300 Oj:compat 0.173 578526.262
301 Oj 0.179 558362.880
302 Ox 0.196 510589.629
303 MessagePack 0.317 315307.220
304 Yajl 0.776 128794.279
305 JSON::Ext 3.511 28483.812
306 JSON::Pure 7.389 13533.717
6234873 ready for a release
Peter Ohler authored
307
308 Comparison Matrix
309 (performance factor, 2.0 row is means twice as fast as column)
53e3bbc added benchmarks
Peter Ohler authored
310 Oj:compat Oj Ox MessagePack Yajl JSON::Ext JSON::Pure
311 ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
312 Oj:compat 1.00 1.04 1.13 1.83 4.49 20.31 42.75
313 Oj 0.97 1.00 1.09 1.77 4.34 19.60 41.26
314 Ox 0.88 0.91 1.00 1.62 3.96 17.93 37.73
315 MessagePack 0.55 0.56 0.62 1.00 2.45 11.07 23.30
316 Yajl 0.22 0.23 0.25 0.41 1.00 4.52 9.52
317 JSON::Ext 0.05 0.05 0.06 0.09 0.22 1.00 2.10
318 JSON::Pure 0.02 0.02 0.03 0.04 0.11 0.48 1.00
6234873 ready for a release
Peter Ohler authored
319
6248665 ready for use with limitations
Peter Ohler authored
320 ### Simple JSON Writing and Parsing:
321
322 require 'oj'
323
324 h = { 'one' => 1, 'array' => [ true, false ] }
325 json = Oj.dump(h)
326
327 # json =
328 # {
329 # "one":1,
330 # "array":[
331 # true,
332 # false
333 # ]
334 # }
335
9b9a86f @sferik Fix typo
sferik authored
336 h2 = Oj.load(json)
6248665 ready for use with limitations
Peter Ohler authored
337 puts "Same? #{h == h2}"
338 # true
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
339
340 ### Object JSON format:
341
342 In :object mode Oj generates JSON that follows conventions which allow Class
343 and other information such as Object IDs for circular reference detection. The
344 formating follows the following rules.
345
346 1. JSON native types, true, false, nil, String, Hash, Array, and Number are
347 encoded normally.
348
6b22c57 finishing off circular reference implementation
Peter Ohler authored
349 2. A Symbol is encoded as a JSON string with a preceeding `:` character.
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
350
6b22c57 finishing off circular reference implementation
Peter Ohler authored
351 3. The `^` character denotes a special key value when in a JSON Object sequence.
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
352
6b22c57 finishing off circular reference implementation
Peter Ohler authored
353 4. A Ruby String that starts with `:` or the sequence `^i` or `^r` are encoded by
354 excaping the first character so that it appears as `\u005e` or `\u003a` instead of
355 `:` or `^`.
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
356
6b22c57 finishing off circular reference implementation
Peter Ohler authored
357 5. A `"^c"` JSON Object key indicates the value should be converted to a Ruby
358 class. The sequence `{"^c":"Oj::Bag"}` is read as the Oj::Bag class.
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
359
6b22c57 finishing off circular reference implementation
Peter Ohler authored
360 6. A `"^t"` JSON Object key indicates the value should be converted to a Ruby
c9bb99f adding new encodings
Peter Ohler authored
361 Time. The sequence `{"^t":1325775487.000000}` is read as Jan 5, 2012 at
362 23:58:07. Similarly, `"^d"` is for a Date and `"^T"` is for a DateTime.
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
363
c9bb99f adding new encodings
Peter Ohler authored
364 7. A `"^o"` JSON Object key indicates the value should be converted to a Ruby
6b22c57 finishing off circular reference implementation
Peter Ohler authored
365 Object. The first entry in the JSON Object must be a class with the `"^o"`
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
366 key. After that each entry is treated as a variable of the Object where the
6b22c57 finishing off circular reference implementation
Peter Ohler authored
367 key is the variable name without the preceeding `@`. An example is
368 `{"^o":"Oj::Bag","x":58,"y":"marbles"}`.
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
369
6b22c57 finishing off circular reference implementation
Peter Ohler authored
370 8. A `"^u"` JSON Object key indicates the value should be converted to a Ruby
371 Struct. The first entry in the JSON Object must be a class with the `"^u"`
0dfa515 now dumping struct in the correct format. Loading still unimplemented
Peter Ohler authored
372 key. After that each entry is is given a numeric position in the struct and
6b22c57 finishing off circular reference implementation
Peter Ohler authored
373 that is used as the key in the JSON Object. An example is `{"^u":["Range",1,7,false]}`.
0dfa515 now dumping struct in the correct format. Loading still unimplemented
Peter Ohler authored
374
6b22c57 finishing off circular reference implementation
Peter Ohler authored
375 9. When encoding an Object, if the variable name does not begin with an `@`
376 character then the name preceeded by a `~` character. This occurs in the
377 Exception class. An example is `{"^o":"StandardError","~mesg":"A Message","~bt":[".\/tests.rb:345:in `test_exception'"]}`.
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
378
6b22c57 finishing off circular reference implementation
Peter Ohler authored
379 10. If a Hash entry has a key that is not a String or Symbol then the entry is
380 encoded with a key of the form `"^#n"` where n is a hex number. The value that
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
381 is an Array where the first element is the key in the Hash and the second is
6b22c57 finishing off circular reference implementation
Peter Ohler authored
382 the value. An example is `{"^#3":[2,5]}`.
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
383
6b22c57 finishing off circular reference implementation
Peter Ohler authored
384 11. A `"^i"` JSON entry in either an Object or Array is the ID of the Ruby
4d28d2c updated readme with message format for object encoding
Peter Ohler authored
385 Object being encoded. It is used when the :circular flag is set. It can appear
6b22c57 finishing off circular reference implementation
Peter Ohler authored
386 in either a JSON Object or in a JSON Array. In an Object the `"^i"` key has a
fdacd8d added hash circular support
Peter Ohler authored
387 corresponding reference Fixnum. In an array the sequence will include an
388 embedded reference number. An example is
6b22c57 finishing off circular reference implementation
Peter Ohler authored
389 `{"^o":"Oj::Bag","^i":1,"x":["^i2",true],"me":"^r1"}`.
390
391 12. A `"^r"` JSON entry in an Object is a references to a Object or Array that
392 already appears in the JSON String. It must match up with a previous `"^i"`
393 ID. An example is `{"^o":"Oj::Bag","^i":1,"x":3,"me":"^r1"}`.
fdacd8d added hash circular support
Peter Ohler authored
394
6b22c57 finishing off circular reference implementation
Peter Ohler authored
395 13. If an Array element is a String and starts with `"^i"` then the first
396 character, the `^` is encoded as a hex character sequence. An example is
397 `["\u005ei37",3]`.
fdacd8d added hash circular support
Peter Ohler authored
398
6b22c57 finishing off circular reference implementation
Peter Ohler authored
399 ### License:
400
401 Copyright (c) 2012, Peter Ohler
402 All rights reserved.
403
404 Redistribution and use in source and binary forms, with or without
405 modification, are permitted provided that the following conditions are met:
406
407 - Redistributions of source code must retain the above copyright notice, this
408 list of conditions and the following disclaimer.
409
410 - Redistributions in binary form must reproduce the above copyright notice,
411 this list of conditions and the following disclaimer in the documentation
412 and/or other materials provided with the distribution.
413
414 - Neither the name of Peter Ohler nor the names of its contributors may be
415 used to endorse or promote products derived from this software without
416 specific prior written permission.
417
418 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
419 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
420 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
421 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
422 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
423 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
424 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
425 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
426 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
427 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Something went wrong with that request. Please try again.