usamin 7.7.0 → 7.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +109 -76
- data/ext/usamin/usamin.cpp +378 -212
- data/lib/usamin.rb +6 -0
- data/lib/usamin/overwrite.rb +26 -0
- data/lib/usamin/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d053f43fdfdf7a7698d45fa5707245c7ea47946c906f3c504f27aabc543f38b1
|
4
|
+
data.tar.gz: 0d2b48bf5962478bd7ce35c1a4cfca68589881b59b62ccff5fadd6addd59be8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: baf083e37d53f5ebfd4ca36e39ec239d62f5f0e198c2a9d79c0efcc77060d5483962d1e1de1268a143ff566713f413f8853a29a68cacc9bc9722d5169abb6cde
|
7
|
+
data.tar.gz: 540f79a2a0015a39b119435b064d683687f248c6405855170dc8fa7469dfcffb4f393df2f33041f4ff1fcd6816f9d2f9808a2249f0ee68f78e685486c6d0c707
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -6,7 +6,7 @@ The name of "Usamin" is derived from [Nana Abe](https://www.project-imas.com/wik
|
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
9
|
-
Install RapidJSON beforehand.
|
9
|
+
Install RapidJSON beforehand. Only header files are necessary, and no need to build.
|
10
10
|
|
11
11
|
Next, add this line to your application's Gemfile:
|
12
12
|
|
@@ -37,24 +37,28 @@ require 'usamin'
|
|
37
37
|
### Parsing
|
38
38
|
|
39
39
|
```ruby
|
40
|
-
json =
|
41
|
-
|
40
|
+
json = <<JSON
|
41
|
+
[
|
42
|
+
{
|
43
|
+
"name": "miku maekawa",
|
42
44
|
"age": 15,
|
43
45
|
"height": 152,
|
44
46
|
"weight": 45,
|
45
47
|
"body_size": [85, 55, 81],
|
46
|
-
"birthday":
|
48
|
+
"birthday": "2/22",
|
47
49
|
"cv": "natsumi takamori"
|
48
50
|
},
|
49
|
-
|
51
|
+
{
|
52
|
+
"name": "nana abe",
|
50
53
|
"age": 17,
|
51
54
|
"height": 146,
|
52
55
|
"weight": 40,
|
53
56
|
"body_size": [84, 57, 84],
|
54
|
-
"birthday":
|
57
|
+
"birthday": "5/15",
|
55
58
|
"cv": "marie miyake"
|
56
59
|
}
|
57
|
-
|
60
|
+
]
|
61
|
+
JSON
|
58
62
|
|
59
63
|
Usamin.parse(json)
|
60
64
|
```
|
@@ -65,37 +69,37 @@ Usamin.parse(json)
|
|
65
69
|
data = Usamin.load(json)
|
66
70
|
```
|
67
71
|
|
68
|
-
Here, `data` is not a
|
72
|
+
Here, `data` is not a Array, but this can be handled like an Array.
|
69
73
|
|
70
74
|
```ruby
|
71
|
-
data.
|
72
|
-
#=>
|
75
|
+
data.size
|
76
|
+
#=> 2
|
73
77
|
|
74
|
-
data.map{|
|
75
|
-
#=>
|
78
|
+
data.map{|e| e['name']}
|
79
|
+
#=> ["miku maekawa", "nana abe"]
|
76
80
|
```
|
77
81
|
|
78
|
-
|
82
|
+
Objects also can be handled like Hash objects.
|
79
83
|
|
80
84
|
```ruby
|
81
|
-
data['
|
82
|
-
#=>
|
85
|
+
data.first['name']
|
86
|
+
#=> "miku maekawa"
|
83
87
|
|
84
|
-
data
|
85
|
-
#=>
|
88
|
+
data.first.keys
|
89
|
+
#=> ["name", "age", "height", "weight", "body_size", "birthday", "cv"]
|
86
90
|
```
|
87
91
|
|
88
|
-
The `eval` and `eval_r`
|
92
|
+
The methods `eval` and `eval_r` convert these data structures into Ruby data structures. `_r` means recursiveness.
|
89
93
|
|
90
94
|
```ruby
|
91
95
|
data.eval
|
92
|
-
#=>
|
96
|
+
#=> [#<Usamin::Hash>, #<Usamin::Hash>]
|
93
97
|
|
94
|
-
data
|
95
|
-
#=> {"age"=>15, "height"=>152, "weight"=>45, "body_size"=>[85, 55, 81], "birthday"=>
|
98
|
+
data.first.eval_r
|
99
|
+
#=> {"name"=>"miku maekawa", "age"=>15, "height"=>152, "weight"=>45, "body_size"=>[85, 55, 81], "birthday"=>"2/22", "cv"=>"natsumi takamori"}
|
96
100
|
|
97
|
-
|
98
|
-
|
101
|
+
# same as Usamin.parse(json)
|
102
|
+
Usamin.load(json).eval_r
|
99
103
|
```
|
100
104
|
|
101
105
|
#### Notes about lazy loading data
|
@@ -106,21 +110,14 @@ data.eval_r
|
|
106
110
|
### Generating
|
107
111
|
|
108
112
|
```ruby
|
109
|
-
data = {
|
110
|
-
"
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
"nana abe"=> {
|
118
|
-
"age"=>17,
|
119
|
-
"height"=>146,
|
120
|
-
"weight"=>40,
|
121
|
-
"body_size"=>[84, 57, 84],
|
122
|
-
"birthday"=>[5, 15],
|
123
|
-
"cv"=>"marie miyake"}}
|
113
|
+
data = [{"name" => "miku maekawa", "age" => 15,
|
114
|
+
"height" => 152, "weight" => 45,
|
115
|
+
"body_size" => [85, 55, 81], "birthday" => "2/22",
|
116
|
+
"cv" => "natsumi takamori"}, {
|
117
|
+
"name" => "nana abe", "age" => 17,
|
118
|
+
"height" => 146, "weight" => 40,
|
119
|
+
"body_size" => [84, 57, 84], "birthday" => "5/15",
|
120
|
+
"cv" => "marie miyake"}]
|
124
121
|
|
125
122
|
Usamin.generate(data)
|
126
123
|
|
@@ -132,8 +129,7 @@ Of course, UsaminValue also can be serialized.
|
|
132
129
|
|
133
130
|
```ruby
|
134
131
|
data = Usamin.load(json)
|
135
|
-
|
136
|
-
Usamin.generate(data['nana abe'])
|
132
|
+
Usamin.generate(data[1])
|
137
133
|
```
|
138
134
|
|
139
135
|
### Fast parsing
|
@@ -160,6 +156,37 @@ Usamin.parse(str)
|
|
160
156
|
# Usamin::ParserError: Missing a colon after a name of object member. Offset: 22
|
161
157
|
```
|
162
158
|
|
159
|
+
### Overwrite JSON module
|
160
|
+
|
161
|
+
You can overwrite JSON module methods by loading `usamin/overwrite`.
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
require 'usamin/overwrite'
|
165
|
+
|
166
|
+
# These methods are based on Usamin
|
167
|
+
JSON.parse(json)
|
168
|
+
JSON.generate(data)
|
169
|
+
JSON.pretty_generate(data)
|
170
|
+
```
|
171
|
+
|
172
|
+
The overwritten methods are as follows:
|
173
|
+
|
174
|
+
- JSON.parse -> Usamin.parse
|
175
|
+
- JSON.load / JSON.restore -> Usamin.parse
|
176
|
+
- JSON.generate -> Usamin.generate / Usamin.pretty_generate
|
177
|
+
- JSON.pretty_generate -> Usamin.pretty_generate
|
178
|
+
|
179
|
+
You can automatically switch packages by following technique.
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
begin
|
183
|
+
require 'usamin'
|
184
|
+
require 'usamin/overwrite'
|
185
|
+
rescue LoadError
|
186
|
+
require 'json'
|
187
|
+
end
|
188
|
+
```
|
189
|
+
|
163
190
|
### Documentation
|
164
191
|
|
165
192
|
See: http://www.rubydoc.info/gems/usamin/
|
@@ -184,66 +211,72 @@ The values show the elapsed time for operating 20 times.
|
|
184
211
|
|
185
212
|
```
|
186
213
|
nativejson-benchmark/data/canada.json
|
187
|
-
json 0.
|
188
|
-
oj 1.
|
189
|
-
usamin 0.
|
190
|
-
usamin (fast) 0.
|
191
|
-
usamin (load) 0.
|
192
|
-
usamin (load / fast) 0.
|
214
|
+
json 0.755101 0.004066 0.759167 ( 0.762169)
|
215
|
+
oj 1.873840 0.040992 1.914832 ( 1.919647)
|
216
|
+
usamin 0.582432 0.011584 0.594016 ( 0.596472)
|
217
|
+
usamin (fast) 0.271741 0.004775 0.276516 ( 0.278315)
|
218
|
+
usamin (load) 0.458602 0.009857 0.468459 ( 0.471155)
|
219
|
+
usamin (load / fast) 0.183260 0.019372 0.202632 ( 0.204489)
|
193
220
|
|
194
221
|
nativejson-benchmark/data/citm_catalog.json
|
195
|
-
json 0.
|
196
|
-
oj 0.
|
197
|
-
usamin 0.
|
198
|
-
usamin (fast) 0.
|
199
|
-
usamin (load) 0.
|
200
|
-
usamin (load / fast) 0.
|
222
|
+
json 0.477735 0.006309 0.484044 ( 0.487179)
|
223
|
+
oj 0.374920 0.005170 0.380090 ( 0.384444)
|
224
|
+
usamin 0.363176 0.004812 0.367988 ( 0.370558)
|
225
|
+
usamin (fast) 0.352986 0.004893 0.357879 ( 0.360197)
|
226
|
+
usamin (load) 0.123704 0.006770 0.130474 ( 0.133101)
|
227
|
+
usamin (load / fast) 0.106889 0.008363 0.115252 ( 0.117514)
|
201
228
|
|
202
229
|
nativejson-benchmark/data/twitter.json
|
203
|
-
json 0.
|
204
|
-
oj 0.
|
205
|
-
usamin 0.
|
206
|
-
usamin (fast) 0.
|
207
|
-
usamin (load) 0.
|
208
|
-
usamin (load / fast) 0.
|
230
|
+
json 0.227502 0.001665 0.229167 ( 0.233347)
|
231
|
+
oj 0.148312 0.000936 0.149248 ( 0.151006)
|
232
|
+
usamin 0.178398 0.003571 0.181969 ( 0.183786)
|
233
|
+
usamin (fast) 0.170842 0.000973 0.171815 ( 0.173604)
|
234
|
+
usamin (load) 0.064007 0.005254 0.069261 ( 0.071036)
|
235
|
+
usamin (load / fast) 0.068870 0.006189 0.075059 ( 0.077111)
|
209
236
|
```
|
210
237
|
|
211
238
|
#### Generating
|
212
239
|
|
213
240
|
```
|
214
241
|
nativejson-benchmark/data/canada.json
|
215
|
-
json 1.
|
216
|
-
oj 2.
|
217
|
-
usamin 0.
|
242
|
+
json 1.994007 0.026034 2.020041 ( 2.025446)
|
243
|
+
oj 2.087961 0.029023 2.116984 ( 2.123429)
|
244
|
+
usamin 0.274208 0.022461 0.296669 ( 0.298859)
|
245
|
+
usamin (load) 0.273885 0.031334 0.305219 ( 0.310155)
|
218
246
|
|
219
247
|
nativejson-benchmark/data/citm_catalog.json
|
220
|
-
json 0.
|
221
|
-
oj 0.
|
222
|
-
usamin 0.
|
248
|
+
json 0.237936 0.009822 0.247758 ( 0.252693)
|
249
|
+
oj 0.073700 0.008512 0.082212 ( 0.084021)
|
250
|
+
usamin 0.064633 0.010208 0.074841 ( 0.077269)
|
251
|
+
usamin (load) 0.041944 0.010903 0.052847 ( 0.055097)
|
223
252
|
|
224
253
|
nativejson-benchmark/data/twitter.json
|
225
|
-
json 0.
|
226
|
-
oj 0.
|
227
|
-
usamin 0.
|
254
|
+
json 0.165987 0.005908 0.171895 ( 0.176533)
|
255
|
+
oj 0.042210 0.005486 0.047696 ( 0.049477)
|
256
|
+
usamin 0.039056 0.009091 0.048147 ( 0.050299)
|
257
|
+
usamin (load) 0.029979 0.009041 0.039020 ( 0.041219)
|
228
258
|
```
|
229
259
|
|
230
260
|
#### Pretty Generating
|
231
261
|
|
232
262
|
```
|
233
263
|
nativejson-benchmark/data/canada.json
|
234
|
-
json 2.
|
235
|
-
oj 1.
|
236
|
-
usamin 0.
|
264
|
+
json 2.196968 0.067552 2.264520 ( 2.270109)
|
265
|
+
oj 1.549510 0.019002 1.568512 ( 1.573885)
|
266
|
+
usamin 0.373060 0.071227 0.444287 ( 0.446266)
|
267
|
+
usamin (load) 0.363781 0.067480 0.431261 ( 0.433839)
|
237
268
|
|
238
269
|
nativejson-benchmark/data/citm_catalog.json
|
239
|
-
json 0.
|
240
|
-
oj 0.
|
241
|
-
usamin 0.
|
270
|
+
json 0.285428 0.022632 0.308060 ( 0.312022)
|
271
|
+
oj 0.064475 0.008716 0.073191 ( 0.075125)
|
272
|
+
usamin 0.088890 0.019419 0.108309 ( 0.110423)
|
273
|
+
usamin (load) 0.058728 0.018471 0.077199 ( 0.079330)
|
242
274
|
|
243
275
|
nativejson-benchmark/data/twitter.json
|
244
|
-
json 0.
|
245
|
-
oj 0.
|
246
|
-
usamin 0.
|
276
|
+
json 0.170966 0.010184 0.181150 ( 0.186188)
|
277
|
+
oj 0.038465 0.007323 0.045788 ( 0.047589)
|
278
|
+
usamin 0.046873 0.011960 0.058833 ( 0.060903)
|
279
|
+
usamin (load) 0.038984 0.010469 0.049453 ( 0.049652)
|
247
280
|
```
|
248
281
|
|
249
282
|
## Contributing
|
data/ext/usamin/usamin.cpp
CHANGED
@@ -211,6 +211,170 @@ static inline VALUE eval_array_r(rapidjson::Value &value) {
|
|
211
211
|
}
|
212
212
|
|
213
213
|
|
214
|
+
template <class Writer> static inline void write_str(Writer&, const VALUE);
|
215
|
+
template <class Writer> static inline void write_hash(Writer&, const VALUE);
|
216
|
+
template <class Writer> static inline void write_array(Writer&, const VALUE);
|
217
|
+
template <class Writer> static inline void write_bignum(Writer&, const VALUE);
|
218
|
+
template <class Writer> static inline void write_struct(Writer&, const VALUE);
|
219
|
+
template <class Writer> static inline void write_usamin(Writer&, const VALUE);
|
220
|
+
template <class Writer> static inline void write_to_s(Writer&, const VALUE);
|
221
|
+
|
222
|
+
template <class Writer> static void write(Writer &writer, const VALUE value) {
|
223
|
+
if (value == Qnil) {
|
224
|
+
writer.Null();
|
225
|
+
} else if (value == Qfalse) {
|
226
|
+
writer.Bool(false);
|
227
|
+
} else if (value == Qtrue) {
|
228
|
+
writer.Bool(true);
|
229
|
+
} else if (RB_FIXNUM_P(value)) {
|
230
|
+
writer.Int64(FIX2LONG(value));
|
231
|
+
} else if (RB_FLOAT_TYPE_P(value)) {
|
232
|
+
writer.Double(NUM2DBL(value));
|
233
|
+
} else if (RB_STATIC_SYM_P(value)) {
|
234
|
+
write_str(writer, rb_sym_to_s(value));
|
235
|
+
} else {
|
236
|
+
switch (RB_BUILTIN_TYPE(value)) {
|
237
|
+
case T_STRING:
|
238
|
+
write_str(writer, value);
|
239
|
+
break;
|
240
|
+
case T_HASH:
|
241
|
+
write_hash(writer, value);
|
242
|
+
break;
|
243
|
+
case T_ARRAY:
|
244
|
+
write_array(writer, value);
|
245
|
+
break;
|
246
|
+
case T_BIGNUM:
|
247
|
+
write_bignum(writer, value);
|
248
|
+
break;
|
249
|
+
case T_STRUCT:
|
250
|
+
write_struct(writer, value);
|
251
|
+
break;
|
252
|
+
default:
|
253
|
+
if (rb_obj_is_kind_of(value, rb_cUsaminValue))
|
254
|
+
write_usamin(writer, value);
|
255
|
+
else
|
256
|
+
write_to_s(writer, value);
|
257
|
+
break;
|
258
|
+
}
|
259
|
+
}
|
260
|
+
}
|
261
|
+
|
262
|
+
template <class Writer> static inline void write_str(Writer &writer, const VALUE value) {
|
263
|
+
VALUE v = get_utf8_str(value);
|
264
|
+
writer.String(RSTRING_PTR(v), static_cast<unsigned int>(RSTRING_LEN(v)));
|
265
|
+
}
|
266
|
+
|
267
|
+
template <class Writer> static inline void write_key_str(Writer &writer, const VALUE value) {
|
268
|
+
VALUE v = get_utf8_str(value);
|
269
|
+
writer.Key(RSTRING_PTR(v), static_cast<unsigned int>(RSTRING_LEN(v)));
|
270
|
+
}
|
271
|
+
|
272
|
+
template <class Writer> static inline void write_key_to_s(Writer &writer, const VALUE value) {
|
273
|
+
write_key_str(writer, rb_funcall(value, id_to_s, 0));
|
274
|
+
}
|
275
|
+
|
276
|
+
template <class Writer> static inline int write_hash_each(VALUE key, VALUE value, Writer *writer) {
|
277
|
+
if (RB_TYPE_P(key, T_STRING))
|
278
|
+
write_key_str(*writer, key);
|
279
|
+
else if (RB_TYPE_P(key, T_SYMBOL))
|
280
|
+
write_key_str(*writer, rb_sym_to_s(key));
|
281
|
+
else
|
282
|
+
write_key_to_s(*writer, key);
|
283
|
+
write(*writer, value);
|
284
|
+
return ST_CONTINUE;
|
285
|
+
}
|
286
|
+
|
287
|
+
template <class Writer> static inline void write_hash(Writer &writer, const VALUE hash) {
|
288
|
+
writer.StartObject();
|
289
|
+
rb_hash_foreach(hash, (int (*)(ANYARGS))write_hash_each<Writer>, reinterpret_cast<VALUE>((&writer)));
|
290
|
+
writer.EndObject();
|
291
|
+
}
|
292
|
+
|
293
|
+
template <class Writer> static inline void write_array(Writer &writer, const VALUE value) {
|
294
|
+
writer.StartArray();
|
295
|
+
const VALUE *ptr = rb_array_const_ptr(value);
|
296
|
+
for (long i = 0; i < rb_array_len(value); i++, ptr++)
|
297
|
+
write(writer, *ptr);
|
298
|
+
writer.EndArray();
|
299
|
+
}
|
300
|
+
|
301
|
+
template <class Writer> static inline void write_bignum(Writer &writer, const VALUE value) {
|
302
|
+
VALUE v = rb_big2str(value, 10);
|
303
|
+
writer.RawValue(RSTRING_PTR(v), static_cast<unsigned int>(RSTRING_LEN(v)), rapidjson::kNumberType);
|
304
|
+
}
|
305
|
+
|
306
|
+
template <class Writer> static inline void write_struct(Writer &writer, const VALUE value) {
|
307
|
+
writer.StartObject();
|
308
|
+
VALUE members = rb_struct_members(value);
|
309
|
+
const VALUE *ptr = rb_array_const_ptr(members);
|
310
|
+
for (long i = 0; i < rb_array_len(members); i++, ptr++) {
|
311
|
+
if (RB_TYPE_P(*ptr, T_SYMBOL))
|
312
|
+
write_key_str(writer, rb_sym_to_s(*ptr));
|
313
|
+
else if (RB_TYPE_P(*ptr, T_STRING))
|
314
|
+
write_key_str(writer, *ptr);
|
315
|
+
else
|
316
|
+
write_key_to_s(writer, *ptr);
|
317
|
+
write(writer, rb_struct_aref(value, *ptr));
|
318
|
+
}
|
319
|
+
writer.EndObject();
|
320
|
+
}
|
321
|
+
|
322
|
+
template <class Writer> static void write_value(Writer &writer, rapidjson::Value &value) {
|
323
|
+
switch (value.GetType()) {
|
324
|
+
case rapidjson::kObjectType:
|
325
|
+
writer.StartObject();
|
326
|
+
for (auto &m : value.GetObject()) {
|
327
|
+
writer.Key(m.name.GetString(), m.name.GetStringLength());
|
328
|
+
write_value(writer, m.value);
|
329
|
+
}
|
330
|
+
writer.EndObject();
|
331
|
+
break;
|
332
|
+
case rapidjson::kArrayType:
|
333
|
+
writer.StartArray();
|
334
|
+
for (auto &v : value.GetArray())
|
335
|
+
write_value(writer, v);
|
336
|
+
writer.EndArray();
|
337
|
+
break;
|
338
|
+
case rapidjson::kNullType:
|
339
|
+
writer.Null();
|
340
|
+
break;
|
341
|
+
case rapidjson::kFalseType:
|
342
|
+
writer.Bool(false);
|
343
|
+
break;
|
344
|
+
case rapidjson::kTrueType:
|
345
|
+
writer.Bool(true);
|
346
|
+
break;
|
347
|
+
case rapidjson::kNumberType:
|
348
|
+
if (value.IsInt())
|
349
|
+
writer.Int(value.GetInt());
|
350
|
+
else if (value.IsUint())
|
351
|
+
writer.Uint(value.GetUint());
|
352
|
+
else if (value.IsInt64())
|
353
|
+
writer.Int64(value.GetInt64());
|
354
|
+
else if (value.IsUint64())
|
355
|
+
writer.Uint64(value.GetUint64());
|
356
|
+
else
|
357
|
+
writer.Double(value.GetDouble());
|
358
|
+
break;
|
359
|
+
case rapidjson::kStringType:
|
360
|
+
writer.String(value.GetString(), value.GetStringLength());
|
361
|
+
break;
|
362
|
+
default:
|
363
|
+
rb_raise(rb_eUsaminError, "Unknown Value Type: %d", value.GetType());
|
364
|
+
}
|
365
|
+
}
|
366
|
+
|
367
|
+
template <class Writer> static inline void write_usamin(Writer &writer, const VALUE self) {
|
368
|
+
UsaminValue *value = get_value(self);
|
369
|
+
check_value(value);
|
370
|
+
write_value(writer, *(value->value));
|
371
|
+
}
|
372
|
+
|
373
|
+
template <class Writer> static inline void write_to_s(Writer &writer, const VALUE value) {
|
374
|
+
write_str(writer, rb_funcall(value, id_to_s, 0));
|
375
|
+
}
|
376
|
+
|
377
|
+
|
214
378
|
UsaminValue::UsaminValue(rapidjson::Value *value, bool free_flag) {
|
215
379
|
this->value = value;
|
216
380
|
this->free_flag = free_flag;
|
@@ -319,7 +483,8 @@ static VALUE w_value_eval(const VALUE self) {
|
|
319
483
|
return eval_object(*(value->value));
|
320
484
|
else if (value->value->IsArray())
|
321
485
|
return eval_array(*(value->value));
|
322
|
-
|
486
|
+
else
|
487
|
+
return Qnil;
|
323
488
|
}
|
324
489
|
|
325
490
|
/*
|
@@ -340,8 +505,6 @@ static VALUE w_value_isfrozen(const VALUE self) {
|
|
340
505
|
return Qtrue;
|
341
506
|
}
|
342
507
|
|
343
|
-
template <class Writer> static void write_value(Writer&, rapidjson::Value&);
|
344
|
-
|
345
508
|
/*
|
346
509
|
* Dumps data in JSON.
|
347
510
|
*
|
@@ -352,7 +515,7 @@ static VALUE w_value_marshal_dump(const VALUE self) {
|
|
352
515
|
check_value(value);
|
353
516
|
rapidjson::StringBuffer buf;
|
354
517
|
rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
|
355
|
-
write_value(writer, *
|
518
|
+
write_value(writer, *value->value);
|
356
519
|
return rb_str_new(buf.GetString(), buf.GetSize());
|
357
520
|
}
|
358
521
|
|
@@ -381,8 +544,7 @@ static VALUE w_value_marshal_load(const VALUE self, VALUE source) {
|
|
381
544
|
|
382
545
|
|
383
546
|
/*
|
384
|
-
* @
|
385
|
-
* @return [Object | nil]
|
547
|
+
* @return [Object | nil]
|
386
548
|
*
|
387
549
|
* @note This method has linear time complexity.
|
388
550
|
*/
|
@@ -397,14 +559,13 @@ static VALUE w_hash_operator_indexer(const VALUE self, VALUE key) {
|
|
397
559
|
}
|
398
560
|
|
399
561
|
static VALUE hash_enum_size(const VALUE self, VALUE args, VALUE eobj) {
|
400
|
-
|
401
|
-
check_object(value);
|
402
|
-
return UINT2NUM(value->value->MemberCount());
|
562
|
+
return UINT2NUM(get_value(self)->value->MemberCount());
|
403
563
|
}
|
404
564
|
|
405
565
|
/*
|
406
566
|
* @yield [key, value]
|
407
567
|
* @yieldparam key [String]
|
568
|
+
* @yieldparam value [Object]
|
408
569
|
* @return [Enumerator | self]
|
409
570
|
*/
|
410
571
|
static VALUE w_hash_each(const VALUE self) {
|
@@ -456,6 +617,28 @@ static VALUE w_hash_isempty(const VALUE self) {
|
|
456
617
|
return value->value->MemberCount() == 0 ? Qtrue : Qfalse;
|
457
618
|
}
|
458
619
|
|
620
|
+
/*
|
621
|
+
* @overload fetch(key, default = nil)
|
622
|
+
* @param [String] key
|
623
|
+
* @param [Object] default
|
624
|
+
* @return [Object]
|
625
|
+
*
|
626
|
+
* @overload fetch(key)
|
627
|
+
* @param [String] key
|
628
|
+
* @yield [key]
|
629
|
+
* @return [Object]
|
630
|
+
*/
|
631
|
+
static VALUE w_hash_fetch(const int argc, VALUE* argv, const VALUE self) {
|
632
|
+
rb_check_arity(argc, 1, 2);
|
633
|
+
UsaminValue *value = get_value(self);
|
634
|
+
check_object(value);
|
635
|
+
VALUE kvalue = get_utf8_str(argv[0]);
|
636
|
+
for (auto &m : value->value->GetObject())
|
637
|
+
if (str_compare(RSTRING_PTR(kvalue), RSTRING_LEN(kvalue), m.name.GetString(), m.name.GetStringLength()))
|
638
|
+
return eval(m.value);
|
639
|
+
return argc == 2 ? argv[1] : rb_block_given_p() ? rb_yield(argv[0]) : Qnil;
|
640
|
+
}
|
641
|
+
|
459
642
|
/*
|
460
643
|
* @note This method has linear time complexity.
|
461
644
|
*/
|
@@ -490,6 +673,34 @@ static VALUE w_hash_length(const VALUE self) {
|
|
490
673
|
return UINT2NUM(value->value->MemberCount());
|
491
674
|
}
|
492
675
|
|
676
|
+
/*
|
677
|
+
* @yield [key, value]
|
678
|
+
* @yieldparam key [String]
|
679
|
+
* @yieldparam value [Object]
|
680
|
+
* @return [Enumerator | ::Hash]
|
681
|
+
*/
|
682
|
+
static VALUE w_hash_select(const VALUE self) {
|
683
|
+
UsaminValue *value = get_value(self);
|
684
|
+
check_object(value);
|
685
|
+
RETURN_SIZED_ENUMERATOR(self, 0, nullptr, hash_enum_size);
|
686
|
+
VALUE hash = rb_hash_new();
|
687
|
+
if (rb_proc_arity(rb_block_proc()) > 1) {
|
688
|
+
for (auto &m : value->value->GetObject()) {
|
689
|
+
VALUE args[] = { eval_str(m.name), eval(m.value) };
|
690
|
+
if (RTEST(rb_yield_values2(2, args)))
|
691
|
+
rb_hash_aset(hash, args[0], args[1]);
|
692
|
+
}
|
693
|
+
} else {
|
694
|
+
for (auto &m : value->value->GetObject()) {
|
695
|
+
VALUE key = eval_str(m.name);
|
696
|
+
VALUE val = eval(m.value);
|
697
|
+
if (RTEST(rb_yield(rb_assoc_new(key, val))))
|
698
|
+
rb_hash_aset(hash, key, val);
|
699
|
+
}
|
700
|
+
}
|
701
|
+
return hash;
|
702
|
+
}
|
703
|
+
|
493
704
|
/*
|
494
705
|
* Convert to Ruby Hash. Same as {Value#eval}.
|
495
706
|
*
|
@@ -532,45 +743,57 @@ static VALUE w_array_operator_indexer(const int argc, VALUE* argv, const VALUE s
|
|
532
743
|
rb_check_arity(argc, 1, 2);
|
533
744
|
UsaminValue *value = get_value(self);
|
534
745
|
check_array(value);
|
746
|
+
rapidjson::SizeType sz = value->value->Size();
|
535
747
|
if (argc == 2) {
|
536
|
-
long beg =
|
537
|
-
long len =
|
748
|
+
long beg = FIX2LONG(argv[0]);
|
749
|
+
long len = FIX2LONG(argv[1]);
|
538
750
|
if (beg < 0)
|
539
|
-
beg
|
751
|
+
beg += sz;
|
540
752
|
if (beg >= 0 && len >= 0) {
|
541
|
-
|
542
|
-
if (end >
|
543
|
-
end =
|
753
|
+
rapidjson::SizeType end = static_cast<rapidjson::SizeType>(beg + len);
|
754
|
+
if (end > sz)
|
755
|
+
end = sz;
|
544
756
|
VALUE ret = rb_ary_new2(end - beg);
|
545
|
-
for (
|
546
|
-
rb_ary_push(ret, eval((*
|
757
|
+
for (rapidjson::SizeType i = static_cast<rapidjson::SizeType>(beg); i < end; i++)
|
758
|
+
rb_ary_push(ret, eval((*value->value)[i]));
|
547
759
|
return ret;
|
548
760
|
}
|
549
761
|
} else if (rb_obj_is_kind_of(argv[0], rb_cRange)) {
|
550
762
|
long beg, len;
|
551
|
-
if (rb_range_beg_len(argv[0], &beg, &len,
|
763
|
+
if (rb_range_beg_len(argv[0], &beg, &len, sz, 0) == Qtrue) {
|
552
764
|
VALUE ret = rb_ary_new2(len);
|
553
|
-
for (
|
554
|
-
rb_ary_push(ret, eval((*
|
765
|
+
for (rapidjson::SizeType i = static_cast<rapidjson::SizeType>(beg); i < beg + len; i++)
|
766
|
+
rb_ary_push(ret, eval((*value->value)[i]));
|
555
767
|
return ret;
|
556
768
|
}
|
557
769
|
} else {
|
558
|
-
long l =
|
770
|
+
long l = FIX2LONG(argv[0]);
|
559
771
|
if (l < 0)
|
560
|
-
l
|
561
|
-
if (l
|
562
|
-
|
563
|
-
if (i < value->value->Size())
|
564
|
-
return eval((*(value->value))[i]);
|
565
|
-
}
|
772
|
+
l += sz;
|
773
|
+
if (0 <= l && l < sz)
|
774
|
+
return eval((*value->value)[static_cast<rapidjson::SizeType>(l)]);
|
566
775
|
}
|
567
776
|
return Qnil;
|
568
777
|
}
|
569
778
|
|
570
|
-
|
779
|
+
/*
|
780
|
+
* @param [Integer] nth
|
781
|
+
* @return [Object]
|
782
|
+
*/
|
783
|
+
static VALUE w_array_at(const VALUE self, VALUE nth) {
|
571
784
|
UsaminValue *value = get_value(self);
|
572
785
|
check_array(value);
|
573
|
-
|
786
|
+
long l = FIX2LONG(nth);
|
787
|
+
rapidjson::SizeType sz = value->value->Size();
|
788
|
+
if (l < 0)
|
789
|
+
l += sz;
|
790
|
+
if (0 <= l && l < sz)
|
791
|
+
return eval((*value->value)[static_cast<rapidjson::SizeType>(l)]);
|
792
|
+
return Qnil;
|
793
|
+
}
|
794
|
+
|
795
|
+
static VALUE array_enum_size(const VALUE self, VALUE args, VALUE eobj) {
|
796
|
+
return UINT2NUM(get_value(self)->value->Size());
|
574
797
|
}
|
575
798
|
|
576
799
|
/*
|
@@ -607,17 +830,60 @@ static VALUE w_array_isempty(const VALUE self) {
|
|
607
830
|
}
|
608
831
|
|
609
832
|
/*
|
610
|
-
* @
|
611
|
-
*
|
833
|
+
* @overload fetch(nth)
|
834
|
+
* @param [Integer] nth
|
835
|
+
* @return [Object]
|
836
|
+
* @raise [IndexError] if nth is out of array bounds
|
837
|
+
*
|
838
|
+
* @overload fetch(nth, ifnone)
|
839
|
+
* @param [Integer] nth
|
840
|
+
* @param [Object] ifnone
|
841
|
+
* @return [Object]
|
842
|
+
*
|
843
|
+
* @overload fetch(nth)
|
844
|
+
* @param [Integer] nth
|
845
|
+
* @yield [nth]
|
846
|
+
* @return [Object]
|
612
847
|
*/
|
613
|
-
static VALUE
|
848
|
+
static VALUE w_array_fetch(const int argc, VALUE* argv, const VALUE self) {
|
849
|
+
rb_check_arity(argc, 1, 2);
|
850
|
+
UsaminValue *value = get_value(self);
|
851
|
+
check_array(value);
|
852
|
+
rapidjson::SizeType sz = value->value->Size();
|
853
|
+
|
854
|
+
long l = FIX2LONG(argv[0]);
|
855
|
+
if (l < 0)
|
856
|
+
l += sz;
|
857
|
+
if (0 <= l && l < sz)
|
858
|
+
return eval((*value->value)[static_cast<rapidjson::SizeType>(l)]);
|
859
|
+
|
860
|
+
if (argc == 2)
|
861
|
+
return argv[1];
|
862
|
+
else if (rb_block_given_p())
|
863
|
+
return rb_yield(argv[0]);
|
864
|
+
else
|
865
|
+
rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%u", FIX2LONG(argv[0]), -static_cast<long>(sz), sz);
|
866
|
+
return Qnil;
|
867
|
+
}
|
868
|
+
|
869
|
+
/*
|
870
|
+
* @overload find_index(val)
|
871
|
+
* @param [Object] val
|
872
|
+
* @return [Integer | nil]
|
873
|
+
*
|
874
|
+
* @overload find_index
|
875
|
+
* @yield [item]
|
876
|
+
* @yieldparam item [Object]
|
877
|
+
* @return [Integer | nil]
|
878
|
+
*/
|
879
|
+
static VALUE w_array_find_index(int argc, VALUE* argv, const VALUE self) {
|
614
880
|
rb_check_arity(argc, 0, 1);
|
615
881
|
UsaminValue *value = get_value(self);
|
616
882
|
check_array(value);
|
617
883
|
|
618
884
|
if (argc == 1) {
|
619
885
|
for (rapidjson::SizeType i = 0; i < value->value->Size(); i++) {
|
620
|
-
if (rb_equal(argv[0], eval((*
|
886
|
+
if (rb_equal(argv[0], eval((*value->value)[i])) == Qtrue)
|
621
887
|
return UINT2NUM(i);
|
622
888
|
}
|
623
889
|
return Qnil;
|
@@ -625,12 +891,26 @@ static VALUE w_array_index(int argc, VALUE* argv, const VALUE self) {
|
|
625
891
|
|
626
892
|
RETURN_SIZED_ENUMERATOR(self, 0, nullptr, array_enum_size);
|
627
893
|
for (rapidjson::SizeType i = 0; i < value->value->Size(); i++) {
|
628
|
-
if (RTEST(rb_yield(eval((*
|
894
|
+
if (RTEST(rb_yield(eval((*value->value)[i]))))
|
629
895
|
return UINT2NUM(i);
|
630
896
|
}
|
631
897
|
return Qnil;
|
632
898
|
}
|
633
899
|
|
900
|
+
/*
|
901
|
+
* @overload index(val)
|
902
|
+
* @param [Object] val
|
903
|
+
* @return [Integer | nil]
|
904
|
+
*
|
905
|
+
* @overload index
|
906
|
+
* @yield [item]
|
907
|
+
* @yieldparam item [Object]
|
908
|
+
* @return [Integer | nil]
|
909
|
+
*/
|
910
|
+
static VALUE w_array_index(int argc, VALUE* argv, const VALUE self) {
|
911
|
+
return w_array_find_index(argc, argv, self);
|
912
|
+
}
|
913
|
+
|
634
914
|
/*
|
635
915
|
* @overload first
|
636
916
|
* @return [Object | nil]
|
@@ -642,24 +922,47 @@ static VALUE w_array_first(const int argc, VALUE* argv, const VALUE self) {
|
|
642
922
|
rb_check_arity(argc, 0, 1);
|
643
923
|
UsaminValue *value = get_value(self);
|
644
924
|
check_array(value);
|
925
|
+
rapidjson::SizeType sz = value->value->Size();
|
645
926
|
|
646
927
|
if (argc == 0) {
|
647
|
-
if (
|
928
|
+
if (sz == 0)
|
648
929
|
return Qnil;
|
649
|
-
return eval(
|
930
|
+
return eval(*value->value->Begin());
|
931
|
+
} else {
|
932
|
+
long l = FIX2LONG(argv[0]);
|
933
|
+
if (l > sz)
|
934
|
+
l = sz;
|
935
|
+
VALUE ret = rb_ary_new2(l);
|
936
|
+
for (auto v = value->value->Begin(); v < value->value->Begin() + l; v++)
|
937
|
+
rb_ary_push(ret, eval(*v));
|
938
|
+
return ret;
|
650
939
|
}
|
940
|
+
}
|
651
941
|
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
942
|
+
/*
|
943
|
+
* @overload last
|
944
|
+
* @return [Object | nil]
|
945
|
+
*
|
946
|
+
* @overload last(n)
|
947
|
+
* @return [::Array<Object>]
|
948
|
+
*/
|
949
|
+
static VALUE w_array_last(const int argc, VALUE* argv, const VALUE self) {
|
950
|
+
rb_check_arity(argc, 0, 1);
|
951
|
+
UsaminValue *value = get_value(self);
|
952
|
+
check_array(value);
|
953
|
+
rapidjson::SizeType sz = value->value->Size();
|
661
954
|
|
662
|
-
|
955
|
+
if (argc == 0) {
|
956
|
+
return sz > 0 ? eval(*(value->value->End() - 1)) : Qnil;
|
957
|
+
} else {
|
958
|
+
long l = FIX2LONG(argv[0]);
|
959
|
+
if (l > sz)
|
960
|
+
l = sz;
|
961
|
+
VALUE ret = rb_ary_new2(l);
|
962
|
+
for (auto v = value->value->End() - l; v < value->value->End(); v++)
|
963
|
+
rb_ary_push(ret, eval(*v));
|
964
|
+
return ret;
|
965
|
+
}
|
663
966
|
}
|
664
967
|
|
665
968
|
/*
|
@@ -671,6 +974,24 @@ static VALUE w_array_length(const VALUE self) {
|
|
671
974
|
return UINT2NUM(value->value->Size());
|
672
975
|
}
|
673
976
|
|
977
|
+
/*
|
978
|
+
* @overload slice(nth)
|
979
|
+
* @param [Integer] nth
|
980
|
+
* @return [Object | nil]
|
981
|
+
*
|
982
|
+
* @overload slice(start, length)
|
983
|
+
* @param [Integer] start
|
984
|
+
* @param [Integer] length
|
985
|
+
* @return [::Array<Object> | nil]
|
986
|
+
*
|
987
|
+
* @overload slice(range)
|
988
|
+
* @param [Range] range
|
989
|
+
* @return [::Array<Object> | nil]
|
990
|
+
*/
|
991
|
+
static VALUE w_array_slice(const int argc, VALUE* argv, const VALUE self) {
|
992
|
+
return w_array_operator_indexer(argc, argv, self);
|
993
|
+
}
|
994
|
+
|
674
995
|
/*
|
675
996
|
* Convert to Ruby data structures. Same as {Value#eval}.
|
676
997
|
*
|
@@ -683,163 +1004,6 @@ static VALUE w_array_eval(const VALUE self) {
|
|
683
1004
|
}
|
684
1005
|
|
685
1006
|
|
686
|
-
template <class Writer> static void write(Writer&, const VALUE);
|
687
|
-
|
688
|
-
template <class Writer> static inline void write_str(Writer &writer, const VALUE value) {
|
689
|
-
VALUE v = get_utf8_str(value);
|
690
|
-
writer.String(RSTRING_PTR(v), static_cast<unsigned int>(RSTRING_LEN(v)));
|
691
|
-
}
|
692
|
-
|
693
|
-
template <class Writer> static inline void write_to_s(Writer &writer, const VALUE value) {
|
694
|
-
write_str(writer, rb_funcall(value, id_to_s, 0));
|
695
|
-
}
|
696
|
-
|
697
|
-
template <class Writer> static inline void write_key_str(Writer &writer, const VALUE value) {
|
698
|
-
VALUE v = get_utf8_str(value);
|
699
|
-
writer.Key(RSTRING_PTR(v), static_cast<unsigned int>(RSTRING_LEN(v)));
|
700
|
-
}
|
701
|
-
|
702
|
-
template <class Writer> static inline void write_key_to_s(Writer &writer, const VALUE value) {
|
703
|
-
write_key_str(writer, rb_funcall(value, id_to_s, 0));
|
704
|
-
}
|
705
|
-
|
706
|
-
template <class Writer> static inline void write_bignum(Writer &writer, const VALUE value) {
|
707
|
-
VALUE v = rb_big2str(value, 10);
|
708
|
-
writer.RawValue(RSTRING_PTR(v), static_cast<unsigned int>(RSTRING_LEN(v)), rapidjson::kNumberType);
|
709
|
-
}
|
710
|
-
|
711
|
-
template <class Writer> static inline int write_hash_each(VALUE key, VALUE value, Writer *writer) {
|
712
|
-
if (RB_TYPE_P(key, T_STRING))
|
713
|
-
write_key_str(*writer, key);
|
714
|
-
else if (RB_TYPE_P(key, T_SYMBOL))
|
715
|
-
write_key_str(*writer, rb_sym_to_s(key));
|
716
|
-
else
|
717
|
-
write_key_to_s(*writer, key);
|
718
|
-
write(*writer, value);
|
719
|
-
return ST_CONTINUE;
|
720
|
-
}
|
721
|
-
|
722
|
-
template <class Writer> static inline void write_hash(Writer &writer, const VALUE hash) {
|
723
|
-
writer.StartObject();
|
724
|
-
rb_hash_foreach(hash, (int (*)(ANYARGS))write_hash_each<Writer>, reinterpret_cast<VALUE>((&writer)));
|
725
|
-
writer.EndObject();
|
726
|
-
}
|
727
|
-
|
728
|
-
template <class Writer> static inline void write_array(Writer &writer, const VALUE value) {
|
729
|
-
writer.StartArray();
|
730
|
-
const VALUE *ptr = rb_array_const_ptr(value);
|
731
|
-
for (long i = 0; i < rb_array_len(value); i++, ptr++)
|
732
|
-
write(writer, *ptr);
|
733
|
-
writer.EndArray();
|
734
|
-
}
|
735
|
-
|
736
|
-
template <class Writer> static inline void write_struct(Writer &writer, const VALUE value) {
|
737
|
-
writer.StartObject();
|
738
|
-
VALUE members = rb_struct_members(value);
|
739
|
-
const VALUE *ptr = rb_array_const_ptr(members);
|
740
|
-
for (long i = 0; i < rb_array_len(members); i++, ptr++) {
|
741
|
-
if (RB_TYPE_P(*ptr, T_SYMBOL))
|
742
|
-
write_key_str(writer, rb_sym_to_s(*ptr));
|
743
|
-
else if (RB_TYPE_P(*ptr, T_STRING))
|
744
|
-
write_key_str(writer, *ptr);
|
745
|
-
else
|
746
|
-
write_key_to_s(writer, *ptr);
|
747
|
-
write(writer, rb_struct_aref(value, *ptr));
|
748
|
-
}
|
749
|
-
writer.EndObject();
|
750
|
-
}
|
751
|
-
|
752
|
-
template <class Writer> static void write_value(Writer &writer, rapidjson::Value &value) {
|
753
|
-
switch (value.GetType()) {
|
754
|
-
case rapidjson::kObjectType:
|
755
|
-
writer.StartObject();
|
756
|
-
for (auto &m : value.GetObject()) {
|
757
|
-
writer.Key(m.name.GetString(), m.name.GetStringLength());
|
758
|
-
write_value(writer, m.value);
|
759
|
-
}
|
760
|
-
writer.EndObject();
|
761
|
-
break;
|
762
|
-
case rapidjson::kArrayType:
|
763
|
-
writer.StartArray();
|
764
|
-
for (auto &v : value.GetArray())
|
765
|
-
write_value(writer, v);
|
766
|
-
writer.EndArray();
|
767
|
-
break;
|
768
|
-
case rapidjson::kNullType:
|
769
|
-
writer.Null();
|
770
|
-
break;
|
771
|
-
case rapidjson::kFalseType:
|
772
|
-
writer.Bool(false);
|
773
|
-
break;
|
774
|
-
case rapidjson::kTrueType:
|
775
|
-
writer.Bool(true);
|
776
|
-
break;
|
777
|
-
case rapidjson::kNumberType:
|
778
|
-
if (value.IsInt())
|
779
|
-
writer.Int(value.GetInt());
|
780
|
-
else if (value.IsUint())
|
781
|
-
writer.Uint(value.GetUint());
|
782
|
-
else if (value.IsInt64())
|
783
|
-
writer.Int64(value.GetInt64());
|
784
|
-
else if (value.IsUint64())
|
785
|
-
writer.Uint64(value.GetUint64());
|
786
|
-
else
|
787
|
-
writer.Double(value.GetDouble());
|
788
|
-
break;
|
789
|
-
case rapidjson::kStringType:
|
790
|
-
writer.String(value.GetString(), value.GetStringLength());
|
791
|
-
break;
|
792
|
-
default:
|
793
|
-
rb_raise(rb_eUsaminError, "Unknown Value Type: %d", value.GetType());
|
794
|
-
}
|
795
|
-
}
|
796
|
-
|
797
|
-
template <class Writer> static inline void write_usamin(Writer &writer, const VALUE self) {
|
798
|
-
UsaminValue *value = get_value(self);
|
799
|
-
check_value(value);
|
800
|
-
write_value(writer, *(value->value));
|
801
|
-
}
|
802
|
-
|
803
|
-
template <class Writer> static void write(Writer &writer, const VALUE value) {
|
804
|
-
if (value == Qnil) {
|
805
|
-
writer.Null();
|
806
|
-
} else if (value == Qfalse) {
|
807
|
-
writer.Bool(false);
|
808
|
-
} else if (value == Qtrue) {
|
809
|
-
writer.Bool(true);
|
810
|
-
} else if (RB_FIXNUM_P(value)) {
|
811
|
-
writer.Int64(FIX2LONG(value));
|
812
|
-
} else if (RB_FLOAT_TYPE_P(value)) {
|
813
|
-
writer.Double(NUM2DBL(value));
|
814
|
-
} else if (RB_STATIC_SYM_P(value)) {
|
815
|
-
write_str(writer, rb_sym_to_s(value));
|
816
|
-
} else {
|
817
|
-
switch (RB_BUILTIN_TYPE(value)) {
|
818
|
-
case T_STRING:
|
819
|
-
write_str(writer, value);
|
820
|
-
break;
|
821
|
-
case T_HASH:
|
822
|
-
write_hash(writer, value);
|
823
|
-
break;
|
824
|
-
case T_ARRAY:
|
825
|
-
write_array(writer, value);
|
826
|
-
break;
|
827
|
-
case T_BIGNUM:
|
828
|
-
write_bignum(writer, value);
|
829
|
-
break;
|
830
|
-
case T_STRUCT:
|
831
|
-
write_struct(writer, value);
|
832
|
-
break;
|
833
|
-
default:
|
834
|
-
if (rb_obj_is_kind_of(value, rb_cUsaminValue))
|
835
|
-
write_usamin(writer, value);
|
836
|
-
else
|
837
|
-
write_to_s(writer, value);
|
838
|
-
break;
|
839
|
-
}
|
840
|
-
}
|
841
|
-
}
|
842
|
-
|
843
1007
|
/*
|
844
1008
|
* Generate the JSON string from Ruby data structures.
|
845
1009
|
*
|
@@ -857,10 +1021,11 @@ static VALUE w_generate(const VALUE self, VALUE value) {
|
|
857
1021
|
/*
|
858
1022
|
* Generate the prettified JSON string from Ruby data structures.
|
859
1023
|
*
|
860
|
-
* @overload
|
1024
|
+
* @overload pretty_generate(obj, opts = {})
|
861
1025
|
* @param [Object] obj an object to serialize
|
862
1026
|
* @param [::Hash] opts options
|
863
1027
|
* @option opts [String] :indent (' ') a string used to indent
|
1028
|
+
* @option opts [Boolean] :single_line_array (false)
|
864
1029
|
* @return [String]
|
865
1030
|
*/
|
866
1031
|
static VALUE w_pretty_generate(const int argc, VALUE *argv, const VALUE self) {
|
@@ -873,8 +1038,6 @@ static VALUE w_pretty_generate(const int argc, VALUE *argv, const VALUE self) {
|
|
873
1038
|
unsigned int indent_count = 2;
|
874
1039
|
if (argc > 1) {
|
875
1040
|
VALUE v_indent = rb_hash_lookup(options, sym_indent);
|
876
|
-
VALUE v_single_line_array = rb_hash_lookup(options, sym_single_line_array);
|
877
|
-
|
878
1041
|
if (RTEST(v_indent)) {
|
879
1042
|
if (RB_FIXNUM_P(v_indent)) {
|
880
1043
|
long l = FIX2LONG(v_indent);
|
@@ -887,9 +1050,6 @@ static VALUE w_pretty_generate(const int argc, VALUE *argv, const VALUE self) {
|
|
887
1050
|
} else {
|
888
1051
|
const char *indent_str = RSTRING_PTR(v);
|
889
1052
|
switch (indent_str[0]) {
|
890
|
-
case '\0':
|
891
|
-
indent_count = 0;
|
892
|
-
break;
|
893
1053
|
case ' ':
|
894
1054
|
case '\t':
|
895
1055
|
case '\r':
|
@@ -899,7 +1059,6 @@ static VALUE w_pretty_generate(const int argc, VALUE *argv, const VALUE self) {
|
|
899
1059
|
default:
|
900
1060
|
rb_raise(rb_eUsaminError, ":indent must be a repetation of \" \", \"\\t\", \"\\r\" or \"\\n\".");
|
901
1061
|
}
|
902
|
-
|
903
1062
|
for (long i = 1; i < vlen; i++)
|
904
1063
|
if (indent_str[0] != indent_str[i])
|
905
1064
|
rb_raise(rb_eUsaminError, ":indent must be a repetation of \" \", \"\\t\", \"\\r\" or \"\\n\".");
|
@@ -908,7 +1067,7 @@ static VALUE w_pretty_generate(const int argc, VALUE *argv, const VALUE self) {
|
|
908
1067
|
}
|
909
1068
|
}
|
910
1069
|
|
911
|
-
if (RTEST(
|
1070
|
+
if (RTEST(rb_hash_lookup(options, sym_single_line_array)))
|
912
1071
|
writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);
|
913
1072
|
}
|
914
1073
|
writer.SetIndent(indent_char, indent_count);
|
@@ -950,11 +1109,13 @@ extern "C" void Init_usamin(void) {
|
|
950
1109
|
rb_define_alloc_func(rb_cUsaminHash, usamin_alloc);
|
951
1110
|
rb_undef_method(rb_cUsaminHash, "initialize");
|
952
1111
|
rb_define_method(rb_cUsaminHash, "[]", RUBY_METHOD_FUNC(w_hash_operator_indexer), 1);
|
1112
|
+
rb_define_method(rb_cUsaminHash, "assoc", RUBY_METHOD_FUNC(w_hash_operator_indexer), 1);
|
953
1113
|
rb_define_method(rb_cUsaminHash, "each", RUBY_METHOD_FUNC(w_hash_each), 0);
|
954
1114
|
rb_define_method(rb_cUsaminHash, "each_pair", RUBY_METHOD_FUNC(w_hash_each), 0);
|
955
1115
|
rb_define_method(rb_cUsaminHash, "each_key", RUBY_METHOD_FUNC(w_hash_each_key), 0);
|
956
1116
|
rb_define_method(rb_cUsaminHash, "each_value", RUBY_METHOD_FUNC(w_hash_each_value), 0);
|
957
1117
|
rb_define_method(rb_cUsaminHash, "empty?", RUBY_METHOD_FUNC(w_hash_isempty), 0);
|
1118
|
+
rb_define_method(rb_cUsaminHash, "fetch", RUBY_METHOD_FUNC(w_hash_fetch), -1);
|
958
1119
|
rb_define_method(rb_cUsaminHash, "has_key?", RUBY_METHOD_FUNC(w_hash_haskey), 1);
|
959
1120
|
rb_define_method(rb_cUsaminHash, "include?", RUBY_METHOD_FUNC(w_hash_haskey), 1);
|
960
1121
|
rb_define_method(rb_cUsaminHash, "key?", RUBY_METHOD_FUNC(w_hash_haskey), 1);
|
@@ -962,6 +1123,7 @@ extern "C" void Init_usamin(void) {
|
|
962
1123
|
rb_define_method(rb_cUsaminHash, "keys", RUBY_METHOD_FUNC(w_hash_keys), 0);
|
963
1124
|
rb_define_method(rb_cUsaminHash, "length", RUBY_METHOD_FUNC(w_hash_length), 0);
|
964
1125
|
rb_define_method(rb_cUsaminHash, "size", RUBY_METHOD_FUNC(w_hash_length), 0);
|
1126
|
+
rb_define_method(rb_cUsaminHash, "select", RUBY_METHOD_FUNC(w_hash_select), 0);
|
965
1127
|
rb_define_method(rb_cUsaminHash, "to_h", RUBY_METHOD_FUNC(w_hash_eval), 0);
|
966
1128
|
rb_define_method(rb_cUsaminHash, "to_hash", RUBY_METHOD_FUNC(w_hash_eval), 0);
|
967
1129
|
rb_define_method(rb_cUsaminHash, "values", RUBY_METHOD_FUNC(w_hash_values), 0);
|
@@ -971,14 +1133,18 @@ extern "C" void Init_usamin(void) {
|
|
971
1133
|
rb_define_alloc_func(rb_cUsaminArray, usamin_alloc);
|
972
1134
|
rb_undef_method(rb_cUsaminArray, "initialize");
|
973
1135
|
rb_define_method(rb_cUsaminArray, "[]", RUBY_METHOD_FUNC(w_array_operator_indexer), -1);
|
1136
|
+
rb_define_method(rb_cUsaminArray, "at", RUBY_METHOD_FUNC(w_array_at), 1);
|
974
1137
|
rb_define_method(rb_cUsaminArray, "each", RUBY_METHOD_FUNC(w_array_each), 0);
|
975
1138
|
rb_define_method(rb_cUsaminArray, "each_index", RUBY_METHOD_FUNC(w_array_each_index), 0);
|
976
1139
|
rb_define_method(rb_cUsaminArray, "empty?", RUBY_METHOD_FUNC(w_array_isempty), 0);
|
1140
|
+
rb_define_method(rb_cUsaminArray, "fetch", RUBY_METHOD_FUNC(w_array_fetch), -1);
|
1141
|
+
rb_define_method(rb_cUsaminArray, "find_index", RUBY_METHOD_FUNC(w_array_find_index), -1);
|
977
1142
|
rb_define_method(rb_cUsaminArray, "index", RUBY_METHOD_FUNC(w_array_index), -1);
|
978
|
-
rb_define_method(rb_cUsaminArray, "find_index", RUBY_METHOD_FUNC(w_array_index), -1);
|
979
1143
|
rb_define_method(rb_cUsaminArray, "first", RUBY_METHOD_FUNC(w_array_first), -1);
|
1144
|
+
rb_define_method(rb_cUsaminArray, "last", RUBY_METHOD_FUNC(w_array_last), -1);
|
980
1145
|
rb_define_method(rb_cUsaminArray, "length", RUBY_METHOD_FUNC(w_array_length), 0);
|
981
1146
|
rb_define_method(rb_cUsaminArray, "size", RUBY_METHOD_FUNC(w_array_length), 0);
|
1147
|
+
rb_define_method(rb_cUsaminArray, "slice", RUBY_METHOD_FUNC(w_array_slice), -1);
|
982
1148
|
rb_define_method(rb_cUsaminArray, "to_a", RUBY_METHOD_FUNC(w_array_eval), 0);
|
983
1149
|
rb_define_method(rb_cUsaminArray, "to_ary", RUBY_METHOD_FUNC(w_array_eval), 0);
|
984
1150
|
|
data/lib/usamin.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'usamin'
|
2
|
+
|
3
|
+
module JSON
|
4
|
+
def self.generate(object, **options)
|
5
|
+
options[:indent] ? Usamin.pretty_generate(object, indent: options[:indent]) : Usamin.generate(object)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.pretty_generate(object, **options)
|
9
|
+
options[:indent] ? Usamin.pretty_generate(object, indent: options[:indent]) : Usamin.pretty_generate(object)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.parse(source, **options)
|
13
|
+
Usamin.parse(object)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.load(source, proc = nil, **options)
|
17
|
+
ret = Usamin.parse(object)
|
18
|
+
proc.call(ret) if proc
|
19
|
+
ret
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
alias fast_generate generate
|
24
|
+
alias restore load
|
25
|
+
end
|
26
|
+
end
|
data/lib/usamin/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: usamin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.7.
|
4
|
+
version: 7.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ishotihadus
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- ext/usamin/extconf.rb
|
87
87
|
- ext/usamin/usamin.cpp
|
88
88
|
- lib/usamin.rb
|
89
|
+
- lib/usamin/overwrite.rb
|
89
90
|
- lib/usamin/version.rb
|
90
91
|
- usamin.gemspec
|
91
92
|
homepage: https://github.com/Ishotihadus/usamin
|