rapidjson 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4824f0636d8f801de840ebf32bd639258ce1e21a063228beaabd2b4ad6e1760a
4
- data.tar.gz: 04bdbf36fdfd8b2ef289d8ba6e68b9d34c731cd1ffae61c154dd276ed56dc35e
3
+ metadata.gz: 722ff2bcb2ebfc8ab861d5066e53e938933bd03d2e7f4bca7662233fa0a8a314
4
+ data.tar.gz: 59d25e68af12d81bc3b5517a88de320a76a72c6b5d7cc9d26758084bd604b9fe
5
5
  SHA512:
6
- metadata.gz: 74f3d0a620d505b0aa55601830f294794e8a938ee087d9fcc228fc6a83452c2b255b1ddf9c0b3aea1d086808259e6f75744fcd6fb9528361090d2bea9d35a612
7
- data.tar.gz: cff30c2bafab60f467ee59cf8a63691f93dd2de1fb5f07573e54a1303f3f279f9100ec9e1c6991cf5c9e874c25df3f6dd52b3e549aef3e510d0d068ce50f9877
6
+ metadata.gz: 4eea208e695986e0e312c3794ba44852057f86a8159c4d862518482d263f2d13ef94fff481c38e2d7a79f881a13cef08e65eff4d49ded5c85378891bc79dab85
7
+ data.tar.gz: cafbbb2e33c4adecdfac50d1fc0bb34e3c1b019828af29714b0005a8a24955c3914c79e7a9690161589597b3df12928d6adddad8887014fd48fb36b58525f25d
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  (Maybe) Ruby's fastest JSON library! Built using the [RapidJSON C++ library](https://rapidjson.org/)
4
4
 
5
+ No monkey patches, ActiveSupport integration, `json` gem emulation.
6
+
5
7
  ## Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
@@ -42,6 +44,58 @@ RapidJSON.pretty_encode(json_string)
42
44
  # }
43
45
  ```
44
46
 
47
+ By default the encoder is "strict" and will raise an exception
48
+
49
+ ## ActiveSupport
50
+
51
+ RapidJSON provides a drop-in replacement ActiveSupport encoder, with very good compatibility.
52
+ Add the following to an initializer to opt-in.
53
+
54
+ ```
55
+ # config/initializers/rapidjson.rb
56
+
57
+ ActiveSupport::JSON::Encoding.json_encoder = RapidJSON::ActiveSupportEncoder
58
+ ```
59
+
60
+ This makes `model.to_json` ~15x faster, and `nested_hash.to_json` ~27x faster (compred using Rails 7.0)
61
+
62
+ ## JSON gem compatibility
63
+
64
+ Contrary to some other JSON libraries, `RapidJSON` doesn't provice a monkey patch to entirely replace the stdlib JSON gem.
65
+
66
+ However it does provide a module that behave like the stdlib JSON gem and that can be used to monkey patch existing code.
67
+
68
+ ```ruby
69
+ module SomeLibrary
70
+ def do_stuff(payload)
71
+ JSON.parse(payload)
72
+ end
73
+ end
74
+ ```
75
+
76
+ ```ruby
77
+ SomeLibrary::JSON = RapidJSON::JSONGem
78
+ ```
79
+
80
+ Note that this module only use `RapidJSON` when it's certain it is safe to do so. If the JSON gem is called with
81
+ some options that `RapidJSON` doesn't support, it automatically fallbacks to calling the JSON gem.
82
+
83
+ ## Advanced usage
84
+
85
+ By default RapidJSON will only encode "JSON-ready" types: `Hash`, `Array`, `Integer`, `Float`, `String`, `Symbol`, `true`, `false`, and `nil`.
86
+
87
+ RapidJSON::Coder can be initialized with a block which allows the behaviour to be customized. This is how the ActiveSupport encoder and JSON compatibility above are implemented! Just using Ruby :heart:.
88
+
89
+ ```
90
+ RapidJSON::Coder.new do |object, is_key|
91
+ object.to_s # Convert any unknown object to string
92
+ end
93
+ ```
94
+
95
+ The block is called only for unrecognized types. The return value is expected to be a "JSON ready" type which will then be encoded.
96
+
97
+ One additional special type is `RapidJSON::Fragment`, which is interpreted as an existing JSON-encoded string. This can be used to efficiently embed an existing JSON document, or to provide compatibility.
98
+
45
99
  ## Performance
46
100
 
47
101
  Your current JSON parser/encoder is probably fine.
@@ -88,27 +142,6 @@ I spent a week working on YAJL/yajl-ruby, and though I really liked the library,
88
142
 
89
143
  However, if you're happy with your current Ruby JSON library (including `json`) you should keep using it. They're all very good.
90
144
 
91
- ## JSON gem compatibility
92
-
93
- Contrary to some other JSON libraries, `RapidJSON` doesn't provice a monkey patch to entirely replace the stdlib JSON gem.
94
-
95
- However it does provide a module that behave like the stdlib JSON gem and that can be used to monkey patch existing code.
96
-
97
- ```ruby
98
- module SomeLibrary
99
- def do_stuff(payload)
100
- JSON.parse(payload)
101
- end
102
- end
103
- ```
104
-
105
- ```ruby
106
- SomeLibrary::JSON = RapidJSON::JSONGem
107
- ```
108
-
109
- Note that this module only use `RapidJSON` when it's certain it is safe to do so. If the JSON gem is called with
110
- some options that `RapidJSON` doesn't support, it automatically fallbacks to calling the JSON gem.
111
-
112
145
  ## Development
113
146
 
114
147
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -12,9 +12,16 @@ class RubyStringBuffer {
12
12
  mem = RSTRING_PTR(ruby_string);
13
13
  }
14
14
 
15
- void Reserve(size_t size) {
16
- if (capacity - used < size) {
17
- resize(capacity * 2);
15
+ void Reserve(size_t want) {
16
+ if (capacity - used < want) {
17
+ size_t new_capacity = capacity;
18
+ while (new_capacity - used < want) {
19
+ if (new_capacity >= SIZE_MAX / 2) {
20
+ ruby_malloc_size_overflow(capacity, 2);
21
+ }
22
+ new_capacity <<= 1;
23
+ }
24
+ resize(new_capacity);
18
25
  }
19
26
  }
20
27
 
@@ -0,0 +1,90 @@
1
+ #include "ruby.h"
2
+ #include "ruby/encoding.h"
3
+
4
+ /* strlen("\\u2029") == 6 */
5
+ #define ESCAPE_JSON_MAX_LEN 6
6
+
7
+ static inline long
8
+ json_escaped_length(VALUE str)
9
+ {
10
+ const long len = RSTRING_LEN(str);
11
+ if (len >= LONG_MAX / ESCAPE_JSON_MAX_LEN) {
12
+ ruby_malloc_size_overflow(len, ESCAPE_JSON_MAX_LEN);
13
+ }
14
+ return len * ESCAPE_JSON_MAX_LEN;
15
+ }
16
+
17
+ static VALUE
18
+ escape_json(VALUE self, VALUE str)
19
+ {
20
+ if (!RB_TYPE_P(str, T_STRING)) {
21
+ str = rb_convert_type(str, T_STRING, "String", "to_s");
22
+ }
23
+
24
+ rb_encoding *enc = rb_enc_get(str);
25
+ if (enc != rb_utf8_encoding() && enc != rb_usascii_encoding()) {
26
+ rb_raise(rb_eEncCompatError, "input string must be UTF-8 or ASCII");
27
+ }
28
+
29
+ const char *cstr = RSTRING_PTR(str);
30
+ const unsigned long str_len = RSTRING_LEN(str);
31
+ const char *end = cstr + RSTRING_LEN(str);
32
+
33
+ size_t initial_match = strcspn(cstr, "&<>\xe2");
34
+ if (initial_match == str_len) {
35
+ return str;
36
+ }
37
+
38
+ VALUE escaped = rb_str_buf_new(json_escaped_length(str));
39
+ rb_str_resize(escaped, json_escaped_length(str));
40
+ char *buf = RSTRING_PTR(escaped);
41
+ char *dest = buf;
42
+
43
+ memcpy(dest, cstr, initial_match);
44
+ cstr += initial_match;
45
+ dest += initial_match;
46
+
47
+ while (cstr < end) {
48
+ const char c = *cstr++;
49
+
50
+ #define JSON_ESCAPE_CONCAT(s) do { \
51
+ memcpy(dest, ("\\u" s), strlen(s) + 2); \
52
+ dest += strlen(s) + 2; \
53
+ } while (0)
54
+
55
+ if (0) {
56
+ }
57
+ else if (c == '&') {
58
+ JSON_ESCAPE_CONCAT("0026");
59
+ }
60
+ else if (c == '>') {
61
+ JSON_ESCAPE_CONCAT("003e");
62
+ }
63
+ else if (c == '<') {
64
+ JSON_ESCAPE_CONCAT("003c");
65
+ }
66
+ else if (c == '\xe2' && cstr[0] == '\x80' && cstr[1] == '\xa8') {
67
+ JSON_ESCAPE_CONCAT("2028");
68
+ cstr += 2;
69
+ }
70
+ else if (c == '\xe2' && cstr[0] == '\x80' && cstr[1] == '\xa9') {
71
+ JSON_ESCAPE_CONCAT("2029");
72
+ cstr += 2;
73
+ }
74
+ else {
75
+ *dest++ = c;
76
+ }
77
+
78
+ initial_match = strcspn(cstr, "&<>\xe2");
79
+ memcpy(dest, cstr, initial_match);
80
+ cstr += initial_match;
81
+ dest += initial_match;
82
+
83
+ #undef JSON_ESCAPE_CONCAT
84
+ }
85
+
86
+ rb_str_resize(escaped, dest - buf);
87
+ rb_enc_associate(escaped, rb_enc_get(str));
88
+
89
+ return escaped;
90
+ }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RapidJSON
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rapidjson
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Hawthorn
@@ -27,6 +27,7 @@ files:
27
27
  - ext/rapidjson/cext.hh
28
28
  - ext/rapidjson/encoder.hh
29
29
  - ext/rapidjson/extconf.rb
30
+ - ext/rapidjson/json_escape.h
30
31
  - ext/rapidjson/parser.hh
31
32
  - ext/rapidjson/rapidjson/include/rapidjson/allocators.h
32
33
  - ext/rapidjson/rapidjson/include/rapidjson/cursorstreamwrapper.h