jrjackson 0.0.7 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +8 -1
- data/README.md +59 -0
- data/Rakefile +1 -151
- data/benchmarking/.jrubyrc +434 -0
- data/benchmarking/benchmark.rb +92 -20
- data/jrjackson.gemspec +17 -16
- data/lib/jrjackson.rb +2 -10
- data/lib/jrjackson/jars/jrjackson-1.0.jar +0 -0
- data/lib/jrjackson/jrjackson.rb +44 -34
- data/lib/jrjackson/version.rb +1 -1
- data/lib/require_relative_patch.rb +6 -0
- data/pom.xml +86 -0
- data/src/main/java/com/jrjackson/JrJacksonRaw.java +76 -0
- data/src/main/java/com/jrjackson/JrJacksonService.java +29 -0
- data/src/main/java/com/jrjackson/JrJacksonStr.java +80 -0
- data/src/main/java/com/jrjackson/JrJacksonSym.java +80 -0
- data/src/main/java/com/jrjackson/ParseError.java +15 -0
- data/src/main/java/com/jrjackson/RubyObjectDeserializer.java +257 -0
- data/src/main/java/com/jrjackson/RubyObjectSymDeserializer.java +80 -0
- metadata +33 -22
- data/README +0 -44
- data/lib/jrjackson/jackson-core-asl-1.9.5.jar +0 -0
- data/lib/jrjackson/jackson-mapper-asl-1.9.5.jar +0 -0
- data/lib/jrjackson/jackson-smile-1.9.5.jar +0 -0
- data/lib/jrjackson/rubify.rb +0 -35
- data/lib/jrjackson/rubify_with_symbol_keys.rb +0 -34
- data/lib/jrjackson_r.rb +0 -11
- data/lib/jrjackson_r_sym.rb +0 -11
@@ -0,0 +1,29 @@
|
|
1
|
+
package com.jrjackson;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyClass;
|
5
|
+
import org.jruby.RubyModule;
|
6
|
+
import org.jruby.runtime.ObjectAllocator;
|
7
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
8
|
+
import org.jruby.runtime.load.BasicLibraryService;
|
9
|
+
|
10
|
+
import java.io.IOException;
|
11
|
+
|
12
|
+
public class JrJacksonService implements BasicLibraryService {
|
13
|
+
public boolean basicLoad(final Ruby ruby) throws IOException {
|
14
|
+
RubyModule jr_jackson = ruby.defineModule("JrJackson");
|
15
|
+
|
16
|
+
RubyModule jr_jackson_str = ruby.defineModuleUnder("Str", jr_jackson);
|
17
|
+
jr_jackson_str.defineAnnotatedMethods(JrJacksonStr.class);
|
18
|
+
|
19
|
+
RubyModule jr_jackson_raw = ruby.defineModuleUnder("Raw", jr_jackson);
|
20
|
+
jr_jackson_raw.defineAnnotatedMethods(JrJacksonRaw.class);
|
21
|
+
|
22
|
+
RubyModule jr_jackson_sym = ruby.defineModuleUnder("Sym", jr_jackson);
|
23
|
+
jr_jackson_sym.defineAnnotatedMethods(JrJacksonSym.class);
|
24
|
+
|
25
|
+
RubyClass runtimeError = ruby.getRuntimeError();
|
26
|
+
RubyClass parseError = jr_jackson.defineClassUnder("ParseError", runtimeError, runtimeError.getAllocator());
|
27
|
+
return true;
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1,80 @@
|
|
1
|
+
package com.jrjackson;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyClass;
|
5
|
+
import org.jruby.RubyObject;
|
6
|
+
import org.jruby.RubyString;
|
7
|
+
import org.jruby.RubyIO;
|
8
|
+
import org.jruby.anno.JRubyMethod;
|
9
|
+
import org.jruby.anno.JRubyModule;
|
10
|
+
import org.jruby.exceptions.RaiseException;
|
11
|
+
import org.jruby.ext.stringio.RubyStringIO;
|
12
|
+
import org.jruby.java.addons.IOJavaAddons;
|
13
|
+
import org.jruby.javasupport.JavaUtil;
|
14
|
+
import org.jruby.runtime.ThreadContext;
|
15
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
16
|
+
import org.jruby.util.RubyDateFormat;
|
17
|
+
|
18
|
+
import java.io.InputStream;
|
19
|
+
import java.io.IOException;
|
20
|
+
import java.text.DateFormat;
|
21
|
+
import java.util.*;
|
22
|
+
|
23
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
24
|
+
import com.fasterxml.jackson.databind.module.SimpleModule;
|
25
|
+
import com.fasterxml.jackson.core.Version;
|
26
|
+
import com.fasterxml.jackson.core.JsonProcessingException;
|
27
|
+
|
28
|
+
@JRubyModule(name = "JrJacksonStr")
|
29
|
+
public class JrJacksonStr extends RubyObject {
|
30
|
+
private static final ObjectMapper mapper = new ObjectMapper();
|
31
|
+
private static final SimpleModule module = new SimpleModule("JrJacksonStrModule");
|
32
|
+
|
33
|
+
static {
|
34
|
+
mapper.registerModule(module.addDeserializer(Object.class, RubyObjectDeserializer.instance));
|
35
|
+
mapper.setDateFormat(new RubyDateFormat("yyyy-MM-dd HH:mm:ss z", Locale.US, true));
|
36
|
+
}
|
37
|
+
|
38
|
+
public JrJacksonStr(Ruby ruby, RubyClass metaclass) {
|
39
|
+
super(ruby, metaclass);
|
40
|
+
}
|
41
|
+
|
42
|
+
@JRubyMethod(module = true, name = {"parse", "load"}, required = 1)
|
43
|
+
public static IRubyObject parse(ThreadContext context, IRubyObject self, IRubyObject arg) {
|
44
|
+
Ruby ruby = context.getRuntime();
|
45
|
+
try {
|
46
|
+
Object o;
|
47
|
+
if (arg instanceof RubyString) {
|
48
|
+
o = mapper.readValue(arg.toString(), Object.class);
|
49
|
+
} else if ((arg instanceof RubyIO) || (arg instanceof RubyStringIO)) {
|
50
|
+
IRubyObject stream = IOJavaAddons.AnyIO.any_to_inputstream(context, arg);
|
51
|
+
o = mapper.readValue((InputStream)stream.toJava(InputStream.class), Object.class);
|
52
|
+
} else {
|
53
|
+
throw ruby.newArgumentError("Unsupported source. This method accepts String or IO");
|
54
|
+
}
|
55
|
+
return (RubyObject)JavaUtil.convertJavaToRuby(ruby, o);
|
56
|
+
}
|
57
|
+
catch (JsonProcessingException e) {
|
58
|
+
throw ParseError.newParseError(ruby, e.getLocalizedMessage());
|
59
|
+
}
|
60
|
+
catch (IOException e) {
|
61
|
+
throw ruby.newIOError(e.getLocalizedMessage());
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
@JRubyMethod(module = true, name = {"generate", "dump"}, required = 1)
|
66
|
+
public static IRubyObject generate(ThreadContext context, IRubyObject self, IRubyObject arg) {
|
67
|
+
Ruby ruby = context.getRuntime();
|
68
|
+
Object obj = arg.toJava(Object.class);
|
69
|
+
try {
|
70
|
+
String s = mapper.writeValueAsString(obj);
|
71
|
+
return ruby.newString(s);
|
72
|
+
}
|
73
|
+
catch (JsonProcessingException e) {
|
74
|
+
throw ParseError.newParseError(ruby, e.getLocalizedMessage());
|
75
|
+
}
|
76
|
+
catch (IOException e) {
|
77
|
+
throw ruby.newIOError(e.getLocalizedMessage());
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
@@ -0,0 +1,80 @@
|
|
1
|
+
package com.jrjackson;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyClass;
|
5
|
+
import org.jruby.RubyObject;
|
6
|
+
import org.jruby.RubyString;
|
7
|
+
import org.jruby.RubyIO;
|
8
|
+
import org.jruby.anno.JRubyMethod;
|
9
|
+
import org.jruby.anno.JRubyModule;
|
10
|
+
import org.jruby.exceptions.RaiseException;
|
11
|
+
import org.jruby.ext.stringio.RubyStringIO;
|
12
|
+
import org.jruby.java.addons.IOJavaAddons;
|
13
|
+
import org.jruby.javasupport.JavaUtil;
|
14
|
+
import org.jruby.runtime.ThreadContext;
|
15
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
16
|
+
import org.jruby.util.RubyDateFormat;
|
17
|
+
|
18
|
+
import java.io.InputStream;
|
19
|
+
import java.io.IOException;
|
20
|
+
import java.text.DateFormat;
|
21
|
+
import java.util.*;
|
22
|
+
|
23
|
+
import com.fasterxml.jackson.databind.ObjectMapper;
|
24
|
+
import com.fasterxml.jackson.databind.module.SimpleModule;
|
25
|
+
import com.fasterxml.jackson.core.Version;
|
26
|
+
import com.fasterxml.jackson.core.JsonProcessingException;
|
27
|
+
|
28
|
+
@JRubyModule(name = "JrJacksonSym")
|
29
|
+
public class JrJacksonSym extends RubyObject {
|
30
|
+
private static final ObjectMapper mapper = new ObjectMapper();
|
31
|
+
private static final SimpleModule module = new SimpleModule("JrJacksonSymModule");
|
32
|
+
|
33
|
+
static {
|
34
|
+
mapper.registerModule(module.addDeserializer(Object.class, RubyObjectSymDeserializer.instance));
|
35
|
+
mapper.setDateFormat(new RubyDateFormat("yyyy-MM-dd HH:mm:ss z", Locale.US, true));
|
36
|
+
}
|
37
|
+
|
38
|
+
public JrJacksonSym(Ruby ruby, RubyClass metaclass) {
|
39
|
+
super(ruby, metaclass);
|
40
|
+
}
|
41
|
+
|
42
|
+
@JRubyMethod(module = true, name = {"parse", "load"}, required = 1)
|
43
|
+
public static IRubyObject parse(ThreadContext context, IRubyObject self, IRubyObject arg) {
|
44
|
+
Ruby ruby = context.getRuntime();
|
45
|
+
try {
|
46
|
+
Object o;
|
47
|
+
if (arg instanceof RubyString) {
|
48
|
+
o = mapper.readValue(arg.toString(), Object.class);
|
49
|
+
} else if ((arg instanceof RubyIO) || (arg instanceof RubyStringIO)) {
|
50
|
+
IRubyObject stream = IOJavaAddons.AnyIO.any_to_inputstream(context, arg);
|
51
|
+
o = mapper.readValue((InputStream)stream.toJava(InputStream.class), Object.class);
|
52
|
+
} else {
|
53
|
+
throw ruby.newArgumentError("Unsupported source. This method accepts String or IO");
|
54
|
+
}
|
55
|
+
return (RubyObject)JavaUtil.convertJavaToRuby(ruby, o);
|
56
|
+
}
|
57
|
+
catch (JsonProcessingException e) {
|
58
|
+
throw ParseError.newParseError(ruby, e.getLocalizedMessage());
|
59
|
+
}
|
60
|
+
catch (IOException e) {
|
61
|
+
throw ruby.newIOError(e.getLocalizedMessage());
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
@JRubyMethod(module = true, name = {"generate", "dump"}, required = 1)
|
66
|
+
public static IRubyObject generate(ThreadContext context, IRubyObject self, IRubyObject arg) {
|
67
|
+
Ruby ruby = context.getRuntime();
|
68
|
+
Object obj = arg.toJava(Object.class);
|
69
|
+
try {
|
70
|
+
String s = mapper.writeValueAsString(obj);
|
71
|
+
return ruby.newString(s);
|
72
|
+
}
|
73
|
+
catch (JsonProcessingException e) {
|
74
|
+
throw ParseError.newParseError(ruby, e.getLocalizedMessage());
|
75
|
+
}
|
76
|
+
catch (IOException e) {
|
77
|
+
throw ruby.newIOError(e.getLocalizedMessage());
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
package com.jrjackson;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyClass;
|
5
|
+
import org.jruby.RubyException;
|
6
|
+
import org.jruby.anno.JRubyClass;
|
7
|
+
import org.jruby.exceptions.RaiseException;
|
8
|
+
|
9
|
+
@JRubyClass(name = "JrJackson::ParseError", parent = "RuntimeError")
|
10
|
+
public class ParseError {
|
11
|
+
public static RaiseException newParseError(Ruby ruby, String message) {
|
12
|
+
RubyClass errorClass = ruby.getModule("JrJackson").getClass("ParseError");
|
13
|
+
return new RaiseException(RubyException.newException(ruby, errorClass, message), true);
|
14
|
+
}
|
15
|
+
}
|
@@ -0,0 +1,257 @@
|
|
1
|
+
package com.jrjackson;
|
2
|
+
|
3
|
+
import java.io.IOException;
|
4
|
+
import java.util.*;
|
5
|
+
|
6
|
+
import com.fasterxml.jackson.core.*;
|
7
|
+
|
8
|
+
import com.fasterxml.jackson.databind.DeserializationContext;
|
9
|
+
import com.fasterxml.jackson.databind.DeserializationFeature;
|
10
|
+
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
|
11
|
+
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
|
12
|
+
import com.fasterxml.jackson.databind.util.ObjectBuffer;
|
13
|
+
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
14
|
+
|
15
|
+
import org.jruby.Ruby;
|
16
|
+
import org.jruby.RubyObject;
|
17
|
+
import org.jruby.RubyArray;
|
18
|
+
import org.jruby.RubyHash;
|
19
|
+
import org.jruby.RubyString;
|
20
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
21
|
+
import org.jruby.javasupport.JavaUtil;
|
22
|
+
import org.jruby.javasupport.util.RuntimeHelpers;
|
23
|
+
|
24
|
+
|
25
|
+
public class RubyObjectDeserializer
|
26
|
+
extends StdDeserializer<RubyObject>
|
27
|
+
{
|
28
|
+
private static final long serialVersionUID = 1L;
|
29
|
+
|
30
|
+
private final static RubyObject[] NO_OBJECTS = new RubyObject[0];
|
31
|
+
|
32
|
+
protected final static Ruby __ruby__ = Ruby.getGlobalRuntime();
|
33
|
+
|
34
|
+
/**
|
35
|
+
* @since 2.2
|
36
|
+
*/
|
37
|
+
public final static RubyObjectDeserializer instance = new RubyObjectDeserializer();
|
38
|
+
|
39
|
+
public RubyObjectDeserializer() { super(RubyObject.class); }
|
40
|
+
|
41
|
+
/*
|
42
|
+
/**********************************************************
|
43
|
+
/* Deserializer API
|
44
|
+
/**********************************************************
|
45
|
+
*/
|
46
|
+
|
47
|
+
@Override
|
48
|
+
public RubyObject deserialize(JsonParser jp, DeserializationContext ctxt)
|
49
|
+
throws IOException, JsonProcessingException
|
50
|
+
{
|
51
|
+
switch (jp.getCurrentToken()) {
|
52
|
+
case START_OBJECT:
|
53
|
+
return mapObject(jp, ctxt);
|
54
|
+
case START_ARRAY:
|
55
|
+
return mapArray(jp, ctxt);
|
56
|
+
case FIELD_NAME:
|
57
|
+
return mapObject(jp, ctxt);
|
58
|
+
case VALUE_EMBEDDED_OBJECT:
|
59
|
+
return toRuby(jp.getEmbeddedObject());
|
60
|
+
case VALUE_STRING:
|
61
|
+
return rubyString(jp);
|
62
|
+
|
63
|
+
case VALUE_NUMBER_INT:
|
64
|
+
/* [JACKSON-100]: caller may want to get all integral values
|
65
|
+
* returned as BigInteger, for consistency
|
66
|
+
*/
|
67
|
+
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
|
68
|
+
return toRuby(jp.getBigIntegerValue()); // should be optimal, whatever it is
|
69
|
+
}
|
70
|
+
return toRuby(jp.getNumberValue()); // should be optimal, whatever it is
|
71
|
+
|
72
|
+
case VALUE_NUMBER_FLOAT:
|
73
|
+
/* [JACKSON-72]: need to allow overriding the behavior regarding
|
74
|
+
* which type to use
|
75
|
+
*/
|
76
|
+
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
|
77
|
+
return toRuby(jp.getDecimalValue());
|
78
|
+
}
|
79
|
+
return toRuby(Double.valueOf(jp.getDoubleValue()));
|
80
|
+
|
81
|
+
case VALUE_TRUE:
|
82
|
+
return __ruby__.newBoolean(Boolean.TRUE);
|
83
|
+
case VALUE_FALSE:
|
84
|
+
return __ruby__.newBoolean(Boolean.FALSE);
|
85
|
+
|
86
|
+
case VALUE_NULL: // should not get this but...
|
87
|
+
return null;
|
88
|
+
|
89
|
+
case END_ARRAY: // invalid
|
90
|
+
case END_OBJECT: // invalid
|
91
|
+
default:
|
92
|
+
throw ctxt.mappingException(Object.class);
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
@Override
|
97
|
+
public RubyObject deserializeWithType(JsonParser jp, DeserializationContext ctxt,
|
98
|
+
TypeDeserializer typeDeserializer)
|
99
|
+
throws IOException, JsonProcessingException
|
100
|
+
{
|
101
|
+
JsonToken t = jp.getCurrentToken();
|
102
|
+
switch (t) {
|
103
|
+
// First: does it look like we had type id wrapping of some kind?
|
104
|
+
case START_ARRAY:
|
105
|
+
case START_OBJECT:
|
106
|
+
case FIELD_NAME:
|
107
|
+
/* Output can be as JSON Object, Array or scalar: no way to know
|
108
|
+
* a this point:
|
109
|
+
*/
|
110
|
+
return toRuby(typeDeserializer.deserializeTypedFromAny(jp, ctxt));
|
111
|
+
|
112
|
+
/* Otherwise we probably got a "native" type (ones that map
|
113
|
+
* naturally and thus do not need or use type ids)
|
114
|
+
*/
|
115
|
+
case VALUE_STRING:
|
116
|
+
return rubyString(jp);
|
117
|
+
|
118
|
+
case VALUE_NUMBER_INT:
|
119
|
+
// For [JACKSON-100], see above:
|
120
|
+
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
|
121
|
+
return toRuby(jp.getBigIntegerValue());
|
122
|
+
}
|
123
|
+
/* and as per [JACKSON-839], allow "upgrade" to bigger types: out-of-range
|
124
|
+
* entries can not be produced without type, so this should "just work",
|
125
|
+
* even if it is bit unclean
|
126
|
+
*/
|
127
|
+
return toRuby(jp.getNumberValue());
|
128
|
+
|
129
|
+
case VALUE_NUMBER_FLOAT:
|
130
|
+
// For [JACKSON-72], see above
|
131
|
+
if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
|
132
|
+
return toRuby(jp.getDecimalValue());
|
133
|
+
}
|
134
|
+
return __ruby__.newFloat(Double.valueOf(jp.getDoubleValue()));
|
135
|
+
|
136
|
+
case VALUE_TRUE:
|
137
|
+
return __ruby__.newBoolean(Boolean.TRUE);
|
138
|
+
case VALUE_FALSE:
|
139
|
+
return __ruby__.newBoolean(Boolean.FALSE);
|
140
|
+
case VALUE_EMBEDDED_OBJECT:
|
141
|
+
return toRuby(jp.getEmbeddedObject());
|
142
|
+
|
143
|
+
case VALUE_NULL: // should not get this far really but...
|
144
|
+
return null;
|
145
|
+
default:
|
146
|
+
throw ctxt.mappingException(Object.class);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
/*
|
151
|
+
/**********************************************************
|
152
|
+
/* Internal methods
|
153
|
+
/**********************************************************
|
154
|
+
*/
|
155
|
+
|
156
|
+
protected RubyObject toRuby(Object o) {
|
157
|
+
return (RubyObject)JavaUtil.convertJavaToRuby(__ruby__, o);
|
158
|
+
}
|
159
|
+
|
160
|
+
protected RubyString rubyString(JsonParser jp) throws IOException {
|
161
|
+
return __ruby__.newString(jp.getText());
|
162
|
+
}
|
163
|
+
|
164
|
+
/**
|
165
|
+
* Method called to map a JSON Array into a Java value.
|
166
|
+
*/
|
167
|
+
protected RubyObject mapArray(JsonParser jp, DeserializationContext ctxt)
|
168
|
+
throws IOException, JsonProcessingException
|
169
|
+
{
|
170
|
+
// if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
|
171
|
+
// return mapArrayToArray(jp, ctxt);
|
172
|
+
// }
|
173
|
+
// Minor optimization to handle small lists (default size for ArrayList is 10)
|
174
|
+
if (jp.nextToken() == JsonToken.END_ARRAY) {
|
175
|
+
return RubyArray.newArray(__ruby__);
|
176
|
+
}
|
177
|
+
ObjectBuffer buffer = ctxt.leaseObjectBuffer();
|
178
|
+
Object[] values = buffer.resetAndStart();
|
179
|
+
int ptr = 0;
|
180
|
+
long totalSize = 0;
|
181
|
+
do {
|
182
|
+
Object value = deserialize(jp, ctxt);
|
183
|
+
++totalSize;
|
184
|
+
if (ptr >= values.length) {
|
185
|
+
values = buffer.appendCompletedChunk(values);
|
186
|
+
ptr = 0;
|
187
|
+
}
|
188
|
+
values[ptr++] = value;
|
189
|
+
} while (jp.nextToken() != JsonToken.END_ARRAY);
|
190
|
+
// let's create almost full array, with 1/8 slack
|
191
|
+
RubyArray result = RubyArray.newArray(__ruby__, (totalSize + (totalSize >> 3) + 1));
|
192
|
+
buffer.completeAndClearBuffer(values, ptr, result);
|
193
|
+
return result;
|
194
|
+
}
|
195
|
+
|
196
|
+
/**
|
197
|
+
* Method called to map a JSON Object into a Java value.
|
198
|
+
*/
|
199
|
+
protected RubyObject mapObject(JsonParser jp, DeserializationContext ctxt)
|
200
|
+
throws IOException, JsonProcessingException
|
201
|
+
{
|
202
|
+
JsonToken t = jp.getCurrentToken();
|
203
|
+
if (t == JsonToken.START_OBJECT) {
|
204
|
+
t = jp.nextToken();
|
205
|
+
}
|
206
|
+
// 1.6: minor optimization; let's handle 1 and 2 entry cases separately
|
207
|
+
if (t != JsonToken.FIELD_NAME) { // and empty one too
|
208
|
+
// empty map might work; but caller may want to modify... so better just give small modifiable
|
209
|
+
return RubyHash.newHash(__ruby__);
|
210
|
+
}
|
211
|
+
RubyString field1 = rubyString(jp);
|
212
|
+
jp.nextToken();
|
213
|
+
RubyObject value1 = deserialize(jp, ctxt);
|
214
|
+
if (jp.nextToken() != JsonToken.FIELD_NAME) { // single entry; but we want modifiable
|
215
|
+
return RuntimeHelpers.constructHash(__ruby__, field1, value1);
|
216
|
+
}
|
217
|
+
RubyString field2 = rubyString(jp);
|
218
|
+
jp.nextToken();
|
219
|
+
RubyObject value2 = deserialize(jp, ctxt);
|
220
|
+
if (jp.nextToken() != JsonToken.FIELD_NAME) {
|
221
|
+
return RuntimeHelpers.constructHash(__ruby__, field1, value1, field2, value2);
|
222
|
+
}
|
223
|
+
// And then the general case; default map size is 16
|
224
|
+
RubyHash result = RuntimeHelpers.constructHash(__ruby__, field1, value1, field2, value2);
|
225
|
+
do {
|
226
|
+
RubyString fieldName = rubyString(jp);
|
227
|
+
jp.nextToken();
|
228
|
+
result.fastASet(fieldName, deserialize(jp, ctxt));
|
229
|
+
} while (jp.nextToken() != JsonToken.END_OBJECT);
|
230
|
+
return result;
|
231
|
+
}
|
232
|
+
|
233
|
+
/**
|
234
|
+
* Method called to map a JSON Array into a Java Object array (Object[]).
|
235
|
+
*/
|
236
|
+
// protected Object[] mapArrayToArray(JsonParser jp, DeserializationContext ctxt)
|
237
|
+
// throws IOException, JsonProcessingException
|
238
|
+
// {
|
239
|
+
// // Minor optimization to handle small lists (default size for ArrayList is 10)
|
240
|
+
// if (jp.nextToken() == JsonToken.END_ARRAY) {
|
241
|
+
// return NO_OBJECTS;
|
242
|
+
// }
|
243
|
+
// ObjectBuffer buffer = ctxt.leaseObjectBuffer();
|
244
|
+
// Object[] values = buffer.resetAndStart();
|
245
|
+
// int ptr = 0;
|
246
|
+
// do {
|
247
|
+
// Object value = deserialize(jp, ctxt);
|
248
|
+
// if (ptr >= values.length) {
|
249
|
+
// values = buffer.appendCompletedChunk(values);
|
250
|
+
// ptr = 0;
|
251
|
+
// }
|
252
|
+
// values[ptr++] = value;
|
253
|
+
// } while (jp.nextToken() != JsonToken.END_ARRAY);
|
254
|
+
// return buffer.completeAndClearBuffer(values, ptr);
|
255
|
+
// }
|
256
|
+
}
|
257
|
+
|