1 package com.fasterxml.jackson.databind.deser.std;
2
3 import java.io.IOException;
4 import java.util.*;
5
6 import com.fasterxml.jackson.core.*;
7
8 import com.fasterxml.jackson.databind.*;
9 import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
10 import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
11 import com.fasterxml.jackson.databind.deser.ResolvableDeserializer;
12 import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
13 import com.fasterxml.jackson.databind.type.TypeFactory;
14 import com.fasterxml.jackson.databind.util.ClassUtil;
15 import com.fasterxml.jackson.databind.util.ObjectBuffer;
16
17
27 @JacksonStdImpl
28 public class UntypedObjectDeserializer
29 extends StdDeserializer<Object>
30 implements ResolvableDeserializer, ContextualDeserializer
31 {
32 private static final long serialVersionUID = 1L;
33
34 protected final static Object[] NO_OBJECTS = new Object[0];
35
36
41
42 protected JsonDeserializer<Object> _mapDeserializer;
43
44 protected JsonDeserializer<Object> _listDeserializer;
45
46 protected JsonDeserializer<Object> _stringDeserializer;
47
48 protected JsonDeserializer<Object> _numberDeserializer;
49
50
56 protected JavaType _listType;
57
58
64 protected JavaType _mapType;
65
66
69 protected final boolean _nonMerging;
70
71
74 @Deprecated
75 public UntypedObjectDeserializer() {
76 this(null, null);
77 }
78
79 public UntypedObjectDeserializer(JavaType listType, JavaType mapType) {
80 super(Object.class);
81 _listType = listType;
82 _mapType = mapType;
83 _nonMerging = false;
84 }
85
86 @SuppressWarnings("unchecked")
87 public UntypedObjectDeserializer(UntypedObjectDeserializer base,
88 JsonDeserializer<?> mapDeser, JsonDeserializer<?> listDeser,
89 JsonDeserializer<?> stringDeser, JsonDeserializer<?> numberDeser)
90 {
91 super(Object.class);
92 _mapDeserializer = (JsonDeserializer<Object>) mapDeser;
93 _listDeserializer = (JsonDeserializer<Object>) listDeser;
94 _stringDeserializer = (JsonDeserializer<Object>) stringDeser;
95 _numberDeserializer = (JsonDeserializer<Object>) numberDeser;
96 _listType = base._listType;
97 _mapType = base._mapType;
98 _nonMerging = base._nonMerging;
99 }
100
101
104 protected UntypedObjectDeserializer(UntypedObjectDeserializer base,
105 boolean nonMerging)
106 {
107 super(Object.class);
108 _mapDeserializer = base._mapDeserializer;
109 _listDeserializer = base._listDeserializer;
110 _stringDeserializer = base._stringDeserializer;
111 _numberDeserializer = base._numberDeserializer;
112 _listType = base._listType;
113 _mapType = base._mapType;
114 _nonMerging = nonMerging;
115 }
116
117
122
123
128 @SuppressWarnings("unchecked")
129 @Override
130 public void resolve(DeserializationContext ctxt) throws JsonMappingException
131 {
132 JavaType obType = ctxt.constructType(Object.class);
133 JavaType stringType = ctxt.constructType(String.class);
134 TypeFactory tf = ctxt.getTypeFactory();
135
136
144
145
146 if (_listType == null) {
147 _listDeserializer = _clearIfStdImpl(_findCustomDeser(ctxt, tf.constructCollectionType(List.class, obType)));
148 } else {
149
150 _listDeserializer = _findCustomDeser(ctxt, _listType);
151 }
152 if (_mapType == null) {
153 _mapDeserializer = _clearIfStdImpl(_findCustomDeser(ctxt, tf.constructMapType(Map.class, stringType, obType)));
154 } else {
155
156 _mapDeserializer = _findCustomDeser(ctxt, _mapType);
157 }
158 _stringDeserializer = _clearIfStdImpl(_findCustomDeser(ctxt, stringType));
159 _numberDeserializer = _clearIfStdImpl(_findCustomDeser(ctxt, tf.constructType(Number.class)));
160
161
162
163 JavaType unknown = TypeFactory.unknownType();
164 _mapDeserializer = (JsonDeserializer<Object>) ctxt.handleSecondaryContextualization(_mapDeserializer, null, unknown);
165 _listDeserializer = (JsonDeserializer<Object>) ctxt.handleSecondaryContextualization(_listDeserializer, null, unknown);
166 _stringDeserializer = (JsonDeserializer<Object>) ctxt.handleSecondaryContextualization(_stringDeserializer, null, unknown);
167 _numberDeserializer = (JsonDeserializer<Object>) ctxt.handleSecondaryContextualization(_numberDeserializer, null, unknown);
168 }
169
170 protected JsonDeserializer<Object> _findCustomDeser(DeserializationContext ctxt, JavaType type)
171 throws JsonMappingException
172 {
173
174
175 return ctxt.findNonContextualValueDeserializer(type);
176 }
177
178 protected JsonDeserializer<Object> _clearIfStdImpl(JsonDeserializer<Object> deser) {
179 return ClassUtil.isJacksonStdImpl(deser) ? null : deser;
180 }
181
182
186 @Override
187 public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
188 BeanProperty property) throws JsonMappingException
189 {
190
191 boolean preventMerge = (property == null)
192 && Boolean.FALSE.equals(ctxt.getConfig().getDefaultMergeable(Object.class));
193
194
195 if ((_stringDeserializer == null) && (_numberDeserializer == null)
196 && (_mapDeserializer == null) && (_listDeserializer == null)
197 && getClass() == UntypedObjectDeserializer.class) {
198 return Vanilla.instance(preventMerge);
199 }
200 if (preventMerge != _nonMerging) {
201 return new UntypedObjectDeserializer(this, preventMerge);
202 }
203 return this;
204 }
205
206
211
212
216 @Override
217 public boolean isCachable() {
218
222 return true;
223 }
224
225 @Override
226 public Boolean supportsUpdate(DeserializationConfig config) {
227
228 return null;
229 }
230
231 @Override
232 public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
233 {
234 switch (p.getCurrentTokenId()) {
235 case JsonTokenId.ID_START_OBJECT:
236 case JsonTokenId.ID_FIELD_NAME:
237
238
239 case JsonTokenId.ID_END_OBJECT:
240 if (_mapDeserializer != null) {
241 return _mapDeserializer.deserialize(p, ctxt);
242 }
243 return mapObject(p, ctxt);
244 case JsonTokenId.ID_START_ARRAY:
245 if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
246 return mapArrayToArray(p, ctxt);
247 }
248 if (_listDeserializer != null) {
249 return _listDeserializer.deserialize(p, ctxt);
250 }
251 return mapArray(p, ctxt);
252 case JsonTokenId.ID_EMBEDDED_OBJECT:
253 return p.getEmbeddedObject();
254 case JsonTokenId.ID_STRING:
255 if (_stringDeserializer != null) {
256 return _stringDeserializer.deserialize(p, ctxt);
257 }
258 return p.getText();
259
260 case JsonTokenId.ID_NUMBER_INT:
261 if (_numberDeserializer != null) {
262 return _numberDeserializer.deserialize(p, ctxt);
263 }
264
267 if (ctxt.hasSomeOfFeatures(F_MASK_INT_COERCIONS)) {
268 return _coerceIntegral(p, ctxt);
269 }
270 return p.getNumberValue();
271
272 case JsonTokenId.ID_NUMBER_FLOAT:
273 if (_numberDeserializer != null) {
274 return _numberDeserializer.deserialize(p, ctxt);
275 }
276
277 if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
278 return p.getDecimalValue();
279 }
280
281 return p.getNumberValue();
282
283 case JsonTokenId.ID_TRUE:
284 return Boolean.TRUE;
285 case JsonTokenId.ID_FALSE:
286 return Boolean.FALSE;
287
288 case JsonTokenId.ID_NULL:
289 return null;
290
291
292 default:
293 }
294 return ctxt.handleUnexpectedToken(Object.class, p);
295 }
296
297 @Override
298 public Object deserializeWithType(JsonParser p, DeserializationContext ctxt,
299 TypeDeserializer typeDeserializer) throws IOException
300 {
301 switch (p.getCurrentTokenId()) {
302
303 case JsonTokenId.ID_START_ARRAY:
304 case JsonTokenId.ID_START_OBJECT:
305 case JsonTokenId.ID_FIELD_NAME:
306
307 return typeDeserializer.deserializeTypedFromAny(p, ctxt);
308
309 case JsonTokenId.ID_EMBEDDED_OBJECT:
310 return p.getEmbeddedObject();
311
312
313
314 case JsonTokenId.ID_STRING:
315 if (_stringDeserializer != null) {
316 return _stringDeserializer.deserialize(p, ctxt);
317 }
318 return p.getText();
319
320 case JsonTokenId.ID_NUMBER_INT:
321 if (_numberDeserializer != null) {
322 return _numberDeserializer.deserialize(p, ctxt);
323 }
324
325 if (ctxt.hasSomeOfFeatures(F_MASK_INT_COERCIONS)) {
326 return _coerceIntegral(p, ctxt);
327 }
328 return p.getNumberValue();
329
330 case JsonTokenId.ID_NUMBER_FLOAT:
331 if (_numberDeserializer != null) {
332 return _numberDeserializer.deserialize(p, ctxt);
333 }
334 if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
335 return p.getDecimalValue();
336 }
337 return p.getNumberValue();
338
339 case JsonTokenId.ID_TRUE:
340 return Boolean.TRUE;
341 case JsonTokenId.ID_FALSE:
342 return Boolean.FALSE;
343
344 case JsonTokenId.ID_NULL:
345 return null;
346 default:
347 }
348 return ctxt.handleUnexpectedToken(Object.class, p);
349 }
350
351 @SuppressWarnings("unchecked")
352 @Override
353 public Object deserialize(JsonParser p, DeserializationContext ctxt, Object intoValue)
354 throws IOException
355 {
356 if (_nonMerging) {
357 return deserialize(p, ctxt);
358 }
359
360 switch (p.getCurrentTokenId()) {
361 case JsonTokenId.ID_START_OBJECT:
362 case JsonTokenId.ID_FIELD_NAME:
363
364
365 case JsonTokenId.ID_END_OBJECT:
366 if (_mapDeserializer != null) {
367 return _mapDeserializer.deserialize(p, ctxt, intoValue);
368 }
369 if (intoValue instanceof Map<?,?>) {
370 return mapObject(p, ctxt, (Map<Object,Object>) intoValue);
371 }
372 return mapObject(p, ctxt);
373 case JsonTokenId.ID_START_ARRAY:
374 if (_listDeserializer != null) {
375 return _listDeserializer.deserialize(p, ctxt, intoValue);
376 }
377 if (intoValue instanceof Collection<?>) {
378 return mapArray(p, ctxt, (Collection<Object>) intoValue);
379 }
380 if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
381 return mapArrayToArray(p, ctxt);
382 }
383 return mapArray(p, ctxt);
384 case JsonTokenId.ID_EMBEDDED_OBJECT:
385 return p.getEmbeddedObject();
386 case JsonTokenId.ID_STRING:
387 if (_stringDeserializer != null) {
388 return _stringDeserializer.deserialize(p, ctxt, intoValue);
389 }
390 return p.getText();
391
392 case JsonTokenId.ID_NUMBER_INT:
393 if (_numberDeserializer != null) {
394 return _numberDeserializer.deserialize(p, ctxt, intoValue);
395 }
396 if (ctxt.hasSomeOfFeatures(F_MASK_INT_COERCIONS)) {
397 return _coerceIntegral(p, ctxt);
398 }
399 return p.getNumberValue();
400
401 case JsonTokenId.ID_NUMBER_FLOAT:
402 if (_numberDeserializer != null) {
403 return _numberDeserializer.deserialize(p, ctxt, intoValue);
404 }
405 if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
406 return p.getDecimalValue();
407 }
408 return p.getNumberValue();
409 case JsonTokenId.ID_TRUE:
410 return Boolean.TRUE;
411 case JsonTokenId.ID_FALSE:
412 return Boolean.FALSE;
413
414 case JsonTokenId.ID_NULL:
415
416 return null;
417 default:
418 }
419
420 return deserialize(p, ctxt);
421 }
422
423
428
429
432 protected Object mapArray(JsonParser p, DeserializationContext ctxt) throws IOException
433 {
434
435 if (p.nextToken() == JsonToken.END_ARRAY) {
436 return new ArrayList<Object>(2);
437 }
438 Object value = deserialize(p, ctxt);
439 if (p.nextToken() == JsonToken.END_ARRAY) {
440 ArrayList<Object> l = new ArrayList<Object>(2);
441 l.add(value);
442 return l;
443 }
444 Object value2 = deserialize(p, ctxt);
445 if (p.nextToken() == JsonToken.END_ARRAY) {
446 ArrayList<Object> l = new ArrayList<Object>(2);
447 l.add(value);
448 l.add(value2);
449 return l;
450 }
451 ObjectBuffer buffer = ctxt.leaseObjectBuffer();
452 Object[] values = buffer.resetAndStart();
453 int ptr = 0;
454 values[ptr++] = value;
455 values[ptr++] = value2;
456 int totalSize = ptr;
457 do {
458 value = deserialize(p, ctxt);
459 ++totalSize;
460 if (ptr >= values.length) {
461 values = buffer.appendCompletedChunk(values);
462 ptr = 0;
463 }
464 values[ptr++] = value;
465 } while (p.nextToken() != JsonToken.END_ARRAY);
466
467 ArrayList<Object> result = new ArrayList<Object>(totalSize);
468 buffer.completeAndClearBuffer(values, ptr, result);
469 return result;
470 }
471
472 protected Object mapArray(JsonParser p, DeserializationContext ctxt,
473 Collection<Object> result) throws IOException
474 {
475
476
477 while (p.nextToken() != JsonToken.END_ARRAY) {
478 result.add(deserialize(p, ctxt));
479 }
480 return result;
481 }
482
483
486 protected Object mapObject(JsonParser p, DeserializationContext ctxt) throws IOException
487 {
488 String key1;
489
490 JsonToken t = p.getCurrentToken();
491
492 if (t == JsonToken.START_OBJECT) {
493 key1 = p.nextFieldName();
494 } else if (t == JsonToken.FIELD_NAME) {
495 key1 = p.getCurrentName();
496 } else {
497 if (t != JsonToken.END_OBJECT) {
498 return ctxt.handleUnexpectedToken(handledType(), p);
499 }
500 key1 = null;
501 }
502 if (key1 == null) {
503
504 return new LinkedHashMap<String,Object>(2);
505 }
506
507
508
509 p.nextToken();
510 Object value1 = deserialize(p, ctxt);
511
512 String key2 = p.nextFieldName();
513 if (key2 == null) {
514
515 LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>(2);
516 result.put(key1, value1);
517 return result;
518 }
519 p.nextToken();
520 Object value2 = deserialize(p, ctxt);
521
522 String key = p.nextFieldName();
523
524 if (key == null) {
525 LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>(4);
526 result.put(key1, value1);
527 result.put(key2, value2);
528 return result;
529 }
530
531 LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>();
532 result.put(key1, value1);
533 result.put(key2, value2);
534
535 do {
536 p.nextToken();
537 result.put(key, deserialize(p, ctxt));
538 } while ((key = p.nextFieldName()) != null);
539 return result;
540 }
541
542
545 protected Object[] mapArrayToArray(JsonParser p, DeserializationContext ctxt) throws IOException
546 {
547
548 if (p.nextToken() == JsonToken.END_ARRAY) {
549 return NO_OBJECTS;
550 }
551 ObjectBuffer buffer = ctxt.leaseObjectBuffer();
552 Object[] values = buffer.resetAndStart();
553 int ptr = 0;
554 do {
555 Object value = deserialize(p, ctxt);
556 if (ptr >= values.length) {
557 values = buffer.appendCompletedChunk(values);
558 ptr = 0;
559 }
560 values[ptr++] = value;
561 } while (p.nextToken() != JsonToken.END_ARRAY);
562 return buffer.completeAndClearBuffer(values, ptr);
563 }
564
565 protected Object mapObject(JsonParser p, DeserializationContext ctxt,
566 Map<Object,Object> m) throws IOException
567 {
568 JsonToken t = p.getCurrentToken();
569 if (t == JsonToken.START_OBJECT) {
570 t = p.nextToken();
571 }
572 if (t == JsonToken.END_OBJECT) {
573 return m;
574 }
575
576 String key = p.getCurrentName();
577 do {
578 p.nextToken();
579
580 Object old = m.get(key);
581 Object newV;
582
583 if (old != null) {
584 newV = deserialize(p, ctxt, old);
585 } else {
586 newV = deserialize(p, ctxt);
587 }
588 if (newV != old) {
589 m.put(key, newV);
590 }
591 } while ((key = p.nextFieldName()) != null);
592 return m;
593 }
594
595
601
602
606 @JacksonStdImpl
607 public static class Vanilla
608 extends StdDeserializer<Object>
609 {
610 private static final long serialVersionUID = 1L;
611
612 public final static Vanilla std = new Vanilla();
613
614
617 protected final boolean _nonMerging;
618
619 public Vanilla() { this(false); }
620
621 protected Vanilla(boolean nonMerging) {
622 super(Object.class);
623 _nonMerging = nonMerging;
624 }
625
626 public static Vanilla instance(boolean nonMerging) {
627 if (nonMerging) {
628 return new Vanilla(true);
629 }
630 return std;
631 }
632
633 @Override
634 public Boolean supportsUpdate(DeserializationConfig config) {
635
636
637 return _nonMerging ? Boolean.FALSE : null;
638 }
639
640 @Override
641 public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
642 {
643 switch (p.getCurrentTokenId()) {
644 case JsonTokenId.ID_START_OBJECT:
645 {
646 JsonToken t = p.nextToken();
647 if (t == JsonToken.END_OBJECT) {
648 return new LinkedHashMap<String,Object>(2);
649 }
650 }
651 case JsonTokenId.ID_FIELD_NAME:
652 return mapObject(p, ctxt);
653 case JsonTokenId.ID_START_ARRAY:
654 {
655 JsonToken t = p.nextToken();
656 if (t == JsonToken.END_ARRAY) {
657 if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
658 return NO_OBJECTS;
659 }
660 return new ArrayList<Object>(2);
661 }
662 }
663 if (ctxt.isEnabled(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY)) {
664 return mapArrayToArray(p, ctxt);
665 }
666 return mapArray(p, ctxt);
667 case JsonTokenId.ID_EMBEDDED_OBJECT:
668 return p.getEmbeddedObject();
669 case JsonTokenId.ID_STRING:
670 return p.getText();
671
672 case JsonTokenId.ID_NUMBER_INT:
673 if (ctxt.hasSomeOfFeatures(F_MASK_INT_COERCIONS)) {
674 return _coerceIntegral(p, ctxt);
675 }
676 return p.getNumberValue();
677
678 case JsonTokenId.ID_NUMBER_FLOAT:
679 if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
680 return p.getDecimalValue();
681 }
682 return p.getNumberValue();
683
684 case JsonTokenId.ID_TRUE:
685 return Boolean.TRUE;
686 case JsonTokenId.ID_FALSE:
687 return Boolean.FALSE;
688
689 case JsonTokenId.ID_END_OBJECT:
690
691
692 return new LinkedHashMap<String,Object>(2);
693
694 case JsonTokenId.ID_NULL:
695 return null;
696
697
698 default:
699 }
700 return ctxt.handleUnexpectedToken(Object.class, p);
701 }
702
703 @Override
704 public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException
705 {
706 switch (p.getCurrentTokenId()) {
707 case JsonTokenId.ID_START_ARRAY:
708 case JsonTokenId.ID_START_OBJECT:
709 case JsonTokenId.ID_FIELD_NAME:
710 return typeDeserializer.deserializeTypedFromAny(p, ctxt);
711
712 case JsonTokenId.ID_STRING:
713 return p.getText();
714
715 case JsonTokenId.ID_NUMBER_INT:
716 if (ctxt.isEnabled(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS)) {
717 return p.getBigIntegerValue();
718 }
719 return p.getNumberValue();
720
721 case JsonTokenId.ID_NUMBER_FLOAT:
722 if (ctxt.isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
723 return p.getDecimalValue();
724 }
725 return p.getNumberValue();
726
727 case JsonTokenId.ID_TRUE:
728 return Boolean.TRUE;
729 case JsonTokenId.ID_FALSE:
730 return Boolean.FALSE;
731 case JsonTokenId.ID_EMBEDDED_OBJECT:
732 return p.getEmbeddedObject();
733
734 case JsonTokenId.ID_NULL:
735 return null;
736 default:
737 }
738 return ctxt.handleUnexpectedToken(Object.class, p);
739 }
740
741 @SuppressWarnings("unchecked")
742 @Override
743 public Object deserialize(JsonParser p, DeserializationContext ctxt, Object intoValue)
744 throws IOException
745 {
746 if (_nonMerging) {
747 return deserialize(p, ctxt);
748 }
749
750 switch (p.getCurrentTokenId()) {
751 case JsonTokenId.ID_END_OBJECT:
752 case JsonTokenId.ID_END_ARRAY:
753 return intoValue;
754 case JsonTokenId.ID_START_OBJECT:
755 {
756 JsonToken t = p.nextToken();
757 if (t == JsonToken.END_OBJECT) {
758 return intoValue;
759 }
760 }
761 case JsonTokenId.ID_FIELD_NAME:
762 if (intoValue instanceof Map<?,?>) {
763 Map<Object,Object> m = (Map<Object,Object>) intoValue;
764
765 String key = p.getCurrentName();
766 do {
767 p.nextToken();
768
769 Object old = m.get(key);
770 Object newV;
771 if (old != null) {
772 newV = deserialize(p, ctxt, old);
773 } else {
774 newV = deserialize(p, ctxt);
775 }
776 if (newV != old) {
777 m.put(key, newV);
778 }
779 } while ((key = p.nextFieldName()) != null);
780 return intoValue;
781 }
782 break;
783 case JsonTokenId.ID_START_ARRAY:
784 {
785 JsonToken t = p.nextToken();
786 if (t == JsonToken.END_ARRAY) {
787 return intoValue;
788 }
789 }
790
791 if (intoValue instanceof Collection<?>) {
792 Collection<Object> c = (Collection<Object>) intoValue;
793
794 do {
795 c.add(deserialize(p, ctxt));
796 } while (p.nextToken() != JsonToken.END_ARRAY);
797 return intoValue;
798 }
799
800
801 break;
802 }
803
804 return deserialize(p, ctxt);
805 }
806
807 protected Object mapArray(JsonParser p, DeserializationContext ctxt) throws IOException
808 {
809 Object value = deserialize(p, ctxt);
810 if (p.nextToken() == JsonToken.END_ARRAY) {
811 ArrayList<Object> l = new ArrayList<Object>(2);
812 l.add(value);
813 return l;
814 }
815 Object value2 = deserialize(p, ctxt);
816 if (p.nextToken() == JsonToken.END_ARRAY) {
817 ArrayList<Object> l = new ArrayList<Object>(2);
818 l.add(value);
819 l.add(value2);
820 return l;
821 }
822 ObjectBuffer buffer = ctxt.leaseObjectBuffer();
823 Object[] values = buffer.resetAndStart();
824 int ptr = 0;
825 values[ptr++] = value;
826 values[ptr++] = value2;
827 int totalSize = ptr;
828 do {
829 value = deserialize(p, ctxt);
830 ++totalSize;
831 if (ptr >= values.length) {
832 values = buffer.appendCompletedChunk(values);
833 ptr = 0;
834 }
835 values[ptr++] = value;
836 } while (p.nextToken() != JsonToken.END_ARRAY);
837
838 ArrayList<Object> result = new ArrayList<Object>(totalSize);
839 buffer.completeAndClearBuffer(values, ptr, result);
840 return result;
841 }
842
843
846 protected Object[] mapArrayToArray(JsonParser p, DeserializationContext ctxt) throws IOException {
847 ObjectBuffer buffer = ctxt.leaseObjectBuffer();
848 Object[] values = buffer.resetAndStart();
849 int ptr = 0;
850 do {
851 Object value = deserialize(p, ctxt);
852 if (ptr >= values.length) {
853 values = buffer.appendCompletedChunk(values);
854 ptr = 0;
855 }
856 values[ptr++] = value;
857 } while (p.nextToken() != JsonToken.END_ARRAY);
858 return buffer.completeAndClearBuffer(values, ptr);
859 }
860
861
864 protected Object mapObject(JsonParser p, DeserializationContext ctxt) throws IOException
865 {
866
867 String key1 = p.getText();
868 p.nextToken();
869 Object value1 = deserialize(p, ctxt);
870
871 String key2 = p.nextFieldName();
872 if (key2 == null) {
873 LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>(2);
874 result.put(key1, value1);
875 return result;
876 }
877 p.nextToken();
878 Object value2 = deserialize(p, ctxt);
879
880 String key = p.nextFieldName();
881 if (key == null) {
882 LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>(4);
883 result.put(key1, value1);
884 result.put(key2, value2);
885 return result;
886 }
887
888 LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>();
889 result.put(key1, value1);
890 result.put(key2, value2);
891 do {
892 p.nextToken();
893 result.put(key, deserialize(p, ctxt));
894 } while ((key = p.nextFieldName()) != null);
895 return result;
896 }
897 }
898 }
899