1 package com.fasterxml.jackson.dataformat.cbor;
2
3 import java.io.*;
4 import java.math.BigDecimal;
5 import java.math.BigInteger;
6 import java.nio.charset.Charset;
7 import java.util.Arrays;
8
9 import com.fasterxml.jackson.core.*;
10 import com.fasterxml.jackson.core.base.ParserMinimalBase;
11 import com.fasterxml.jackson.core.io.IOContext;
12 import com.fasterxml.jackson.core.io.NumberInput;
13 import com.fasterxml.jackson.core.json.DupDetector;
14 import com.fasterxml.jackson.core.sym.ByteQuadsCanonicalizer;
15 import com.fasterxml.jackson.core.util.ByteArrayBuilder;
16 import com.fasterxml.jackson.core.util.TextBuffer;
17
18 import static com.fasterxml.jackson.dataformat.cbor.CBORConstants.*;
19
20 public class CBORParser extends ParserMinimalBase
21 {
22
25 public enum Feature implements FormatFeature
26 {
27
28 ;
29
30 final boolean _defaultState;
31 final int _mask;
32
33
37 public static int collectDefaults()
38 {
39 int flags = 0;
40 for (Feature f : values()) {
41 if (f.enabledByDefault()) {
42 flags |= f.getMask();
43 }
44 }
45 return flags;
46 }
47
48 private Feature(boolean defaultState) {
49 _defaultState = defaultState;
50 _mask = (1 << ordinal());
51 }
52
53 @Override public boolean enabledByDefault() { return _defaultState; }
54 @Override public int getMask() { return _mask; }
55 @Override public boolean enabledIn(int flags) { return (flags & _mask) != 0; }
56 }
57
58 private final static Charset UTF8 = Charset.forName("UTF-8");
59
60 private final static int[] UTF8_UNIT_CODES = CBORConstants.sUtf8UnitLengths;
61
62
63 private final static double MATH_POW_2_10 = Math.pow(2, 10);
64 private final static double MATH_POW_2_NEG14 = Math.pow(2, -14);
65
66
71
72
75 protected ObjectCodec _objectCodec;
76
77
82
83
87 final protected IOContext _ioContext;
88
89
94 protected boolean _closed;
95
96
101
102
103
104
107 protected int _inputPtr = 0;
108
109
112 protected int _inputEnd = 0;
113
114
119
120
124 protected long _currInputProcessed = 0L;
125
126
130 protected int _currInputRow = 1;
131
132
138 protected int _currInputRowStart = 0;
139
140
146
147
148
149
154 protected long _tokenInputTotal = 0;
155
156
159 protected int _tokenInputRow = 1;
160
161
165 protected int _tokenInputCol = 0;
166
167
172
173
177 protected CBORReadContext _parsingContext;
178
179
184 protected final TextBuffer _textBuffer;
185
186
191 protected char[] _nameCopyBuffer = null;
192
193
198 protected boolean _nameCopied = false;
199
200
204 protected ByteArrayBuilder _byteArrayBuilder = null;
205
206
212 protected byte[] _binaryValue;
213
214
217 protected int _tagValue = -1;
218
219
224
225
230 protected InputStream _inputStream;
231
232
237 protected byte[] _inputBuffer;
238
239
246 protected boolean _bufferRecyclable;
247
248
253
254
259 protected boolean _tokenIncomplete = false;
260
261
264 protected int _typeByte;
265
266
269 private int _chunkLeft, _chunkEnd;
270
271
276
277
280 final protected ByteQuadsCanonicalizer _symbols;
281
282
285 protected int[] _quadBuffer = NO_INTS;
286
287
290 protected int _quad1, _quad2, _quad3;
291
292
297
298
299
300 @SuppressWarnings("hiding")
301 final static BigInteger BI_MIN_INT = BigInteger.valueOf(Integer.MIN_VALUE);
302 @SuppressWarnings("hiding")
303 final static BigInteger BI_MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE);
304
305 @SuppressWarnings("hiding")
306 final static BigInteger BI_MIN_LONG = BigInteger.valueOf(Long.MIN_VALUE);
307 @SuppressWarnings("hiding")
308 final static BigInteger BI_MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE);
309
310 @SuppressWarnings("hiding")
311 final static BigDecimal BD_MIN_LONG = new BigDecimal(BI_MIN_LONG);
312 @SuppressWarnings("hiding")
313 final static BigDecimal BD_MAX_LONG = new BigDecimal(BI_MAX_LONG);
314
315 @SuppressWarnings("hiding")
316 final static BigDecimal BD_MIN_INT = new BigDecimal(BI_MIN_INT);
317 @SuppressWarnings("hiding")
318 final static BigDecimal BD_MAX_INT = new BigDecimal(BI_MAX_INT);
319
320
321
322
323
327 protected int _numTypesValid = NR_UNKNOWN;
328
329
330
331 protected int _numberInt;
332 protected long _numberLong;
333 protected float _numberFloat;
334 protected double _numberDouble;
335
336
337
338 protected BigInteger _numberBigInt;
339 protected BigDecimal _numberBigDecimal;
340
341
346
347 public CBORParser(IOContext ctxt, int parserFeatures, int cborFeatures,
348 ObjectCodec codec, ByteQuadsCanonicalizer sym,
349 InputStream in, byte[] inputBuffer, int start, int end,
350 boolean bufferRecyclable)
351 {
352 super(parserFeatures);
353 _ioContext = ctxt;
354 _objectCodec = codec;
355 _symbols = sym;
356
357 _inputStream = in;
358 _inputBuffer = inputBuffer;
359 _inputPtr = start;
360 _inputEnd = end;
361 _bufferRecyclable = bufferRecyclable;
362 _textBuffer = ctxt.constructTextBuffer();
363 DupDetector dups = JsonParser.Feature.STRICT_DUPLICATE_DETECTION.enabledIn(parserFeatures)
364 ? DupDetector.rootDetector(this) : null;
365 _parsingContext = CBORReadContext.createRootContext(dups);
366
367 _tokenInputRow = -1;
368 _tokenInputCol = -1;
369 }
370
371 @Override
372 public ObjectCodec getCodec() {
373 return _objectCodec;
374 }
375
376 @Override
377 public void setCodec(ObjectCodec c) {
378 _objectCodec = c;
379 }
380
381
386
387 @Override
388 public Version version() {
389 return PackageVersion.VERSION;
390 }
391
392
397
398
399
400 @Override
401 public int getFormatFeatures() {
402
403 return 0;
404 }
405
406
407
408
413
414
422 public int getCurrentTag() {
423 return _tagValue;
424 }
425
426
431
432 @Override
433 public int releaseBuffered(OutputStream out) throws IOException
434 {
435 int count = _inputEnd - _inputPtr;
436 if (count < 1) {
437 return 0;
438 }
439
440 int origPtr = _inputPtr;
441 out.write(_inputBuffer, origPtr, count);
442 return count;
443 }
444
445 @Override
446 public Object getInputSource() {
447 return _inputStream;
448 }
449
450
454 @Override
455 public JsonLocation getTokenLocation()
456 {
457
458 return new JsonLocation(_ioContext.getSourceReference(),
459 _tokenInputTotal,
460 -1, -1, (int) _tokenInputTotal);
461 }
462
463
467 @Override
468 public JsonLocation getCurrentLocation()
469 {
470 final long offset = _currInputProcessed + _inputPtr;
471 return new JsonLocation(_ioContext.getSourceReference(),
472 offset,
473 -1, -1, (int) offset);
474 }
475
476
480 @Override
481 public String getCurrentName() throws IOException
482 {
483 if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) {
484 CBORReadContext parent = _parsingContext.getParent();
485 return parent.getCurrentName();
486 }
487 return _parsingContext.getCurrentName();
488 }
489
490 @Override
491 public void overrideCurrentName(String name)
492 {
493
494 CBORReadContext ctxt = _parsingContext;
495 if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) {
496 ctxt = ctxt.getParent();
497 }
498
499 try {
500 ctxt.setCurrentName(name);
501 } catch (IOException e) {
502 throw new IllegalStateException(e);
503 }
504 }
505
506 @Override
507 public void close() throws IOException {
508 if (!_closed) {
509 _closed = true;
510 _symbols.release();
511 try {
512 _closeInput();
513 } finally {
514
515
516 _releaseBuffers();
517 }
518 }
519 }
520
521 @Override
522 public boolean isClosed() { return _closed; }
523
524 @Override
525 public CBORReadContext getParsingContext() {
526 return _parsingContext;
527 }
528
529
534
535 @Override
536 public boolean hasTextCharacters()
537 {
538 if (_currToken == JsonToken.VALUE_STRING) {
539
540 return _textBuffer.hasTextAsCharacters();
541 }
542 if (_currToken == JsonToken.FIELD_NAME) {
543
544 return _nameCopied;
545 }
546
547 return false;
548 }
549
550
556 protected void _releaseBuffers() throws IOException
557 {
558 if (_bufferRecyclable) {
559 byte[] buf = _inputBuffer;
560 if (buf != null) {
561 _inputBuffer = null;
562 _ioContext.releaseReadIOBuffer(buf);
563 }
564 }
565 _textBuffer.releaseBuffers();
566 char[] buf = _nameCopyBuffer;
567 if (buf != null) {
568 _nameCopyBuffer = null;
569 _ioContext.releaseNameCopyBuffer(buf);
570 }
571 }
572
573
578
579 @Override
580 public JsonToken nextToken() throws IOException
581 {
582 _numTypesValid = NR_UNKNOWN;
583
584 if (_tokenIncomplete) {
585 _skipIncomplete();
586 }
587 _tokenInputTotal = _currInputProcessed + _inputPtr;
588
589 _binaryValue = null;
590
591
595 if (_parsingContext.inObject()) {
596 if (_currToken != JsonToken.FIELD_NAME) {
597 _tagValue = -1;
598
599 if (!_parsingContext.expectMoreValues()) {
600 _parsingContext = _parsingContext.getParent();
601 return (_currToken = JsonToken.END_OBJECT);
602 }
603 return (_currToken = _decodeFieldName());
604 }
605 } else {
606 if (!_parsingContext.expectMoreValues()) {
607 _tagValue = -1;
608 _parsingContext = _parsingContext.getParent();
609 return (_currToken = JsonToken.END_ARRAY);
610 }
611 }
612 if (_inputPtr >= _inputEnd) {
613 if (!loadMore()) {
614 return _handleCBOREOF();
615 }
616 }
617 int ch = _inputBuffer[_inputPtr++];
618 int type = (ch >> 5) & 0x7;
619
620
621 if (type == 6) {
622 _tagValue = Integer.valueOf(_decodeTag(ch & 0x1F));
623 if (_inputPtr >= _inputEnd) {
624 if (!loadMore()) {
625 return _handleCBOREOF();
626 }
627 }
628 ch = _inputBuffer[_inputPtr++];
629 type = (ch >> 5) & 0x7;
630 } else {
631 _tagValue = -1;
632 }
633
634 final int lowBits = ch & 0x1F;
635 switch (type) {
636 case 0:
637 _numTypesValid = NR_INT;
638 if (lowBits <= 23) {
639 _numberInt = lowBits;
640 } else {
641 switch (lowBits - 24) {
642 case 0:
643 _numberInt = _decode8Bits();
644 break;
645 case 1:
646 _numberInt = _decode16Bits();
647 break;
648 case 2:
649
650 {
651 int v = _decode32Bits();
652 if (v >= 0) {
653 _numberInt = v;
654 } else {
655 long l = (long) v;
656 _numberLong = l & 0xFFFFFFFFL;
657 _numTypesValid = NR_LONG;
658 }
659 }
660 break;
661 case 3:
662
663 {
664 long l = _decode64Bits();
665 if (l >= 0L) {
666 _numberLong = l;
667 _numTypesValid = NR_LONG;
668 } else {
669 _numberBigInt = _bigPositive(l);
670 _numTypesValid = NR_BIGINT;
671 }
672 }
673 break;
674 default:
675 _invalidToken(ch);
676 }
677 }
678 return (_currToken = JsonToken.VALUE_NUMBER_INT);
679 case 1:
680 _numTypesValid = NR_INT;
681 if (lowBits <= 23) {
682 _numberInt = -lowBits - 1;
683 } else {
684 switch (lowBits - 24) {
685 case 0:
686 _numberInt = -_decode8Bits() - 1;
687 break;
688 case 1:
689 _numberInt = -_decode16Bits() - 1;
690 break;
691 case 2:
692
693 {
694 int v = _decode32Bits();
695 if (v < 0) {
696 long unsignedBase = (long) v & 0xFFFFFFFFL;
697 _numberLong = -unsignedBase - 1L;
698 _numTypesValid = NR_LONG;
699 } else {
700 _numberInt = -v - 1;
701 }
702 }
703 break;
704 case 3:
705
706 {
707 long l = _decode64Bits();
708 if (l >= 0L) {
709 _numberLong = -l - 1L;
710 _numTypesValid = NR_LONG;
711 } else {
712 _numberBigInt = _bigNegative(l);
713 _numTypesValid = NR_BIGINT;
714 }
715 }
716 break;
717 default:
718 _invalidToken(ch);
719 }
720 }
721 return (_currToken = JsonToken.VALUE_NUMBER_INT);
722
723 case 2:
724 _typeByte = ch;
725 _tokenIncomplete = true;
726 if (_tagValue >= 0) {
727 return _handleTaggedBinary(_tagValue);
728 }
729 return (_currToken = JsonToken.VALUE_EMBEDDED_OBJECT);
730
731 case 3:
732 _typeByte = ch;
733 _tokenIncomplete = true;
734 return (_currToken = JsonToken.VALUE_STRING);
735
736 case 4:
737 {
738 int len = _decodeExplicitLength(lowBits);
739 if (_tagValue >= 0) {
740 return _handleTaggedArray(_tagValue, len);
741 }
742 _parsingContext = _parsingContext.createChildArrayContext(len);
743 }
744 return (_currToken = JsonToken.START_ARRAY);
745
746 case 5:
747 _currToken = JsonToken.START_OBJECT;
748 {
749 int len = _decodeExplicitLength(lowBits);
750 _parsingContext = _parsingContext.createChildObjectContext(len);
751 }
752 return _currToken;
753
754 case 6:
755 _reportError("Multiple tags not allowed per value (first tag: "+_tagValue+")");
756
757 default:
758 switch (lowBits) {
759 case 20:
760 return (_currToken = JsonToken.VALUE_FALSE);
761 case 21:
762 return (_currToken = JsonToken.VALUE_TRUE);
763 case 22:
764 return (_currToken = JsonToken.VALUE_NULL);
765 case 23:
766 return (_currToken = _decodeUndefinedValue());
767
768 case 25:
769
770 {
771 _numberFloat = (float) _decodeHalfSizeFloat();
772 _numTypesValid = NR_FLOAT;
773 }
774 return (_currToken = JsonToken.VALUE_NUMBER_FLOAT);
775 case 26:
776 {
777 _numberFloat = Float.intBitsToFloat(_decode32Bits());
778 _numTypesValid = NR_FLOAT;
779 }
780 return (_currToken = JsonToken.VALUE_NUMBER_FLOAT);
781 case 27:
782 _numberDouble = Double.longBitsToDouble(_decode64Bits());
783 _numTypesValid = NR_DOUBLE;
784 return (_currToken = JsonToken.VALUE_NUMBER_FLOAT);
785 case 31:
786 if (_parsingContext.inArray()) {
787 if (!_parsingContext.hasExpectedLength()) {
788 _parsingContext = _parsingContext.getParent();
789 return (_currToken = JsonToken.END_ARRAY);
790 }
791 }
792
793 _reportUnexpectedBreak();
794 }
795 _invalidToken(ch);
796 }
797 return null;
798 }
799
800 protected String _numberToName(int ch, boolean neg) throws IOException
801 {
802 final int lowBits = ch & 0x1F;
803 int i;
804 if (lowBits <= 23) {
805 i = lowBits;
806 } else {
807 switch (lowBits) {
808 case 24:
809 i = _decode8Bits();
810 break;
811 case 25:
812 i = _decode16Bits();
813 break;
814 case 26:
815 i = _decode32Bits();
816 break;
817 case 27:
818 {
819 long l = _decode64Bits();
820 if (neg) {
821 l = -l - 1L;
822 }
823 return String.valueOf(l);
824 }
825 default:
826 throw _constructError("Invalid length indicator for ints ("+lowBits+"), token 0x"+Integer.toHexString(ch));
827 }
828 }
829 if (neg) {
830 i = -i - 1;
831 }
832 return String.valueOf(i);
833 }
834
835 protected JsonToken _handleTaggedBinary(int tag) throws IOException
836 {
837
838 boolean neg;
839 if (tag == TAG_BIGNUM_POS) {
840 neg = false;
841 } else if (tag == TAG_BIGNUM_NEG) {
842 neg = true;
843 } else {
844
845
846 return (_currToken = JsonToken.VALUE_EMBEDDED_OBJECT);
847 }
848
849
850 _finishToken();
851
852 BigInteger nr = new BigInteger(_binaryValue);
853 if (neg) {
854 nr = nr.negate();
855 }
856 _numberBigInt = nr;
857 _numTypesValid = NR_BIGINT;
858 _tagValue = -1;
859 return (_currToken = JsonToken.VALUE_NUMBER_INT);
860 }
861
862 protected JsonToken _handleTaggedArray(int tag, int len) throws IOException
863 {
864
865
866
867 _parsingContext = _parsingContext.createChildArrayContext(len);
868
869
870 if (tag != CBORConstants.TAG_DECIMAL_FRACTION) {
871 return (_currToken = JsonToken.START_ARRAY);
872 }
873 _currToken = JsonToken.START_ARRAY;
874
875
876 if (len != 2) {
877 _reportError("Unexpected array size ("+len+") for tagged 'bigfloat' value; should have exactly 2 number elements");
878 }
879
880
881 if (!_checkNextIsIntInArray("bigfloat")) {
882 _reportError("Unexpected token ("+currentToken()+") as the first part of 'bigfloat' value: should get VALUE_NUMBER_INT");
883 }
884
885 int exp = -getIntValue();
886
887
888 if (!_checkNextIsIntInArray("bigfloat")) {
889 _reportError("Unexpected token ("+currentToken()+") as the second part of 'bigfloat' value: should get VALUE_NUMBER_INT");
890 }
891
892
893 BigDecimal dec;
894 NumberType numberType = getNumberType();
895 if (numberType == NumberType.BIG_INTEGER) {
896 dec = new BigDecimal(getBigIntegerValue(), exp);
897 } else {
898 dec = BigDecimal.valueOf(getLongValue(), exp);
899 }
900
901
902 if (!_checkNextIsEndArray()) {
903 _reportError("Unexpected token ("+currentToken()+") after 2 elements of 'bigfloat' value");
904 }
905
906
907 _numberBigDecimal = dec;
908 _numTypesValid = NR_BIGDECIMAL;
909 return (_currToken = JsonToken.VALUE_NUMBER_FLOAT);
910 }
911
912
921 protected final boolean _checkNextIsIntInArray(final String typeDesc) throws IOException
922 {
923
924 if (!_parsingContext.expectMoreValues()) {
925 _tagValue = -1;
926 _parsingContext = _parsingContext.getParent();
927 _currToken = JsonToken.END_ARRAY;
928 return false;
929 }
930
931 if (_inputPtr >= _inputEnd) {
932 if (!loadMore()) {
933 _handleCBOREOF();
934 return false;
935 }
936 }
937 int ch = _inputBuffer[_inputPtr++];
938 int type = (ch >> 5) & 0x7;
939
940
941
942 int tagValue = -1;
943 if (type == 6) {
944 tagValue = _decodeTag(ch & 0x1F);
945 if ((_inputPtr >= _inputEnd) && !loadMore()) {
946 _handleCBOREOF();
947 return false;
948 }
949 ch = _inputBuffer[_inputPtr++];
950 type = (ch >> 5) & 0x7;
951 }
952
953 final int lowBits = ch & 0x1F;
954 switch (type) {
955 case 0:
956 _numTypesValid = NR_INT;
957 if (lowBits <= 23) {
958 _numberInt = lowBits;
959 } else {
960 switch (lowBits - 24) {
961 case 0:
962 _numberInt = _decode8Bits();
963 break;
964 case 1:
965 _numberInt = _decode16Bits();
966 break;
967 case 2:
968 {
969 int v = _decode32Bits();
970 if (v >= 0) {
971 _numberInt = v;
972 } else {
973 long l = (long) v;
974 _numberLong = l & 0xFFFFFFFFL;
975 _numTypesValid = NR_LONG;
976 }
977 }
978 break;
979 case 3:
980 {
981 long l = _decode64Bits();
982 if (l >= 0L) {
983 _numberLong = l;
984 _numTypesValid = NR_LONG;
985 } else {
986 _numberBigInt = _bigPositive(l);
987 _numTypesValid = NR_BIGINT;
988 }
989 }
990 break;
991 default:
992 _invalidToken(ch);
993 }
994 }
995 _currToken = JsonToken.VALUE_NUMBER_INT;
996 return true;
997 case 1:
998 _numTypesValid = NR_INT;
999 if (lowBits <= 23) {
1000 _numberInt = -lowBits - 1;
1001 } else {
1002 switch (lowBits - 24) {
1003 case 0:
1004 _numberInt = -_decode8Bits() - 1;
1005 break;
1006 case 1:
1007 _numberInt = -_decode16Bits() - 1;
1008 break;
1009 case 2:
1010
1011 {
1012 int v = _decode32Bits();
1013 if (v < 0) {
1014 long unsignedBase = (long) v & 0xFFFFFFFFL;
1015 _numberLong = -unsignedBase - 1L;
1016 _numTypesValid = NR_LONG;
1017 } else {
1018 _numberInt = -v - 1;
1019 }
1020 }
1021 break;
1022 case 3:
1023
1024 {
1025 long l = _decode64Bits();
1026 if (l >= 0L) {
1027 _numberLong = -l - 1L;
1028 _numTypesValid = NR_LONG;
1029 } else {
1030 _numberBigInt = _bigNegative(l);
1031 _numTypesValid = NR_BIGINT;
1032 }
1033 }
1034 break;
1035 default:
1036 _invalidToken(ch);
1037 }
1038 }
1039 _currToken = JsonToken.VALUE_NUMBER_INT;
1040 return true;
1041
1042 case 2:
1043
1044 if (tagValue < 0) {
1045 break;
1046 }
1047 _typeByte = ch;
1048 _tokenIncomplete = true;
1049 _currToken = _handleTaggedBinary(tagValue);
1050 return (_currToken == JsonToken.VALUE_NUMBER_INT);
1051
1052 case 6:
1053 _reportError("Multiple tags not allowed per value (first tag: "+tagValue+")");
1054 }
1055
1056
1057 --_inputPtr;
1058
1059 nextToken();
1060 return false;
1061 }
1062
1063 protected final boolean _checkNextIsEndArray() throws IOException
1064 {
1065
1066 if (!_parsingContext.expectMoreValues()) {
1067 _tagValue = -1;
1068 _parsingContext = _parsingContext.getParent();
1069 _currToken = JsonToken.END_ARRAY;
1070 return true;
1071 }
1072
1073
1074
1075
1076 int ch = _inputBuffer[_inputPtr++];
1077 int type = (ch >> 5) & 0x7;
1078
1079
1080 int tagValue = -1;
1081 if (type == 6) {
1082 tagValue = _decodeTag(ch & 0x1F);
1083 if ((_inputPtr >= _inputEnd) && !loadMore()) {
1084 _handleCBOREOF();
1085 return false;
1086 }
1087 ch = _inputBuffer[_inputPtr++];
1088 type = (ch >> 5) & 0x7;
1089
1090 if (type == 6) {
1091 _reportError("Multiple tags not allowed per value (first tag: "+tagValue+")");
1092 }
1093 }
1094
1095
1096
1097 --_inputPtr;
1098 return nextToken() == JsonToken.END_ARRAY;
1099 }
1100
1101
1102
1103
1104
1108 @Override
1109 public void finishToken() throws IOException
1110 {
1111 if (_tokenIncomplete) {
1112 _finishToken();
1113 }
1114 }
1115
1116
1121
1122 @Override
1123 public boolean nextFieldName(SerializableString str) throws IOException
1124 {
1125
1126 if (_parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) {
1127 _numTypesValid = NR_UNKNOWN;
1128 if (_tokenIncomplete) {
1129 _skipIncomplete();
1130 }
1131 _tokenInputTotal = _currInputProcessed + _inputPtr;
1132 _binaryValue = null;
1133 _tagValue = -1;
1134
1135 if (!_parsingContext.expectMoreValues()) {
1136 _parsingContext = _parsingContext.getParent();
1137 _currToken = JsonToken.END_OBJECT;
1138 return false;
1139 }
1140 byte[] nameBytes = str.asQuotedUTF8();
1141 final int byteLen = nameBytes.length;
1142
1143 int ptr = _inputPtr;
1144 if ((ptr + byteLen + 1) < _inputEnd) {
1145 final int ch = _inputBuffer[ptr++];
1146
1147 if (((ch >> 5) & 0x7) == CBORConstants.MAJOR_TYPE_TEXT) {
1148 int lenMarker = ch & 0x1F;
1149 if (lenMarker <= 24) {
1150 if (lenMarker == 23) {
1151 lenMarker = _inputBuffer[ptr++] & 0xFF;
1152 }
1153 if (lenMarker == byteLen) {
1154 int i = 0;
1155 while (true) {
1156 if (i == lenMarker) {
1157 _inputPtr = ptr+i;
1158 _parsingContext.setCurrentName(str.getValue());
1159 _currToken = JsonToken.FIELD_NAME;
1160 return true;
1161 }
1162 if (nameBytes[i] != _inputBuffer[ptr+i]) {
1163 break;
1164 }
1165 ++i;
1166 }
1167 }
1168 }
1169 }
1170 }
1171
1172 }
1173
1174 return (nextToken() == JsonToken.FIELD_NAME) && str.getValue().equals(getCurrentName());
1175 }
1176
1177 @Override
1178 public String nextFieldName() throws IOException
1179 {
1180 if (_parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) {
1181 _numTypesValid = NR_UNKNOWN;
1182 if (_tokenIncomplete) {
1183 _skipIncomplete();
1184 }
1185 _tokenInputTotal = _currInputProcessed + _inputPtr;
1186 _binaryValue = null;
1187 _tagValue = -1;
1188
1189 if (!_parsingContext.expectMoreValues()) {
1190 _parsingContext = _parsingContext.getParent();
1191 _currToken = JsonToken.END_OBJECT;
1192 return null;
1193 }
1194
1195
1196 if (_inputPtr >= _inputEnd) {
1197 loadMoreGuaranteed();
1198 }
1199 final int ch = _inputBuffer[_inputPtr++];
1200 final int type = ((ch >> 5) & 0x7);
1201
1202
1203 if (type != CBORConstants.MAJOR_TYPE_TEXT) {
1204 if (ch == -1) {
1205 if (!_parsingContext.hasExpectedLength()) {
1206 _parsingContext = _parsingContext.getParent();
1207 _currToken = JsonToken.END_OBJECT;
1208 return null;
1209 }
1210 _reportUnexpectedBreak();
1211 }
1212 _decodeNonStringName(ch);
1213 _currToken = JsonToken.FIELD_NAME;
1214 return getText();
1215 }
1216 final int lenMarker = ch & 0x1F;
1217 String name;
1218 if (lenMarker <= 23) {
1219 if (lenMarker == 0) {
1220 name = "";
1221 } else {
1222 name = _findDecodedFromSymbols(lenMarker);
1223 if (name != null) {
1224 _inputPtr += lenMarker;
1225 } else {
1226 name = _decodeShortName(lenMarker);
1227 name = _addDecodedToSymbols(lenMarker, name);
1228 }
1229 }
1230 } else {
1231 final int actualLen = _decodeExplicitLength(lenMarker);
1232 if (actualLen < 0) {
1233 name = _decodeChunkedName();
1234 } else {
1235 name = _decodeLongerName(actualLen);
1236 }
1237 }
1238 _parsingContext.setCurrentName(name);
1239 _currToken = JsonToken.FIELD_NAME;
1240 return name;
1241 }
1242
1243 return (nextToken() == JsonToken.FIELD_NAME) ? getCurrentName() : null;
1244 }
1245
1246 @Override
1247 public String nextTextValue() throws IOException
1248 {
1249 _numTypesValid = NR_UNKNOWN;
1250 if (_tokenIncomplete) {
1251 _skipIncomplete();
1252 }
1253 _tokenInputTotal = _currInputProcessed + _inputPtr;
1254 _binaryValue = null;
1255 _tagValue = -1;
1256
1257 if (_parsingContext.inObject()) {
1258 if (_currToken != JsonToken.FIELD_NAME) {
1259 _tagValue = -1;
1260
1261 if (!_parsingContext.expectMoreValues()) {
1262 _parsingContext = _parsingContext.getParent();
1263 _currToken = JsonToken.END_OBJECT;
1264 return null;
1265 }
1266 _currToken = _decodeFieldName();
1267 return null;
1268 }
1269 } else {
1270 if (!_parsingContext.expectMoreValues()) {
1271 _tagValue = -1;
1272 _parsingContext = _parsingContext.getParent();
1273 _currToken = JsonToken.END_ARRAY;
1274 return null;
1275 }
1276 }
1277 if (_inputPtr >= _inputEnd) {
1278 if (!loadMore()) {
1279 _handleCBOREOF();
1280 return null;
1281 }
1282 }
1283 int ch = _inputBuffer[_inputPtr++];
1284 int type = (ch >> 5) & 0x7;
1285
1286
1287 if (type == 6) {
1288 _tagValue = Integer.valueOf(_decodeTag(ch & 0x1F));
1289 if (_inputPtr >= _inputEnd) {
1290 if (!loadMore()) {
1291 _handleCBOREOF();
1292 return null;
1293 }
1294 }
1295 ch = _inputBuffer[_inputPtr++];
1296 type = (ch >> 5) & 0x7;
1297 } else {
1298 _tagValue = -1;
1299 }
1300
1301 final int lowBits = ch & 0x1F;
1302 switch (type) {
1303 case 0:
1304 _numTypesValid = NR_INT;
1305 if (lowBits <= 23) {
1306 _numberInt = lowBits;
1307 } else {
1308 switch (lowBits - 24) {
1309 case 0:
1310 _numberInt = _decode8Bits();
1311 break;
1312 case 1:
1313 _numberInt = _decode16Bits();
1314 break;
1315 case 2:
1316
1317 {
1318 int v = _decode32Bits();
1319 if (v < 0) {
1320 long l = (long) v;
1321 _numberLong = l & 0xFFFFFFFFL;
1322 _numTypesValid = NR_LONG;
1323 } else{
1324 _numberInt = v;
1325 }
1326 }
1327 break;
1328 case 3:
1329
1330 {
1331 long l = _decode64Bits();
1332 if (l >= 0L) {
1333 _numberLong = l;
1334 _numTypesValid = NR_LONG;
1335 } else {
1336 _numberBigInt = _bigPositive(l);
1337 _numTypesValid = NR_BIGINT;
1338 }
1339 }
1340 break;
1341 default:
1342 _invalidToken(ch);
1343 }
1344 }
1345 _currToken = JsonToken.VALUE_NUMBER_INT;
1346 return null;
1347 case 1:
1348 _numTypesValid = NR_INT;
1349 if (lowBits <= 23) {
1350 _numberInt = -lowBits - 1;
1351 } else {
1352 switch (lowBits - 24) {
1353 case 0:
1354 _numberInt = -_decode8Bits() - 1;
1355 break;
1356 case 1:
1357 _numberInt = -_decode16Bits() - 1;
1358 break;
1359 case 2:
1360
1361 {
1362 int v = _decode32Bits();
1363 if (v < 0) {
1364 long unsignedBase = (long) v & 0xFFFFFFFFL;
1365 _numberLong = -unsignedBase - 1L;
1366 _numTypesValid = NR_LONG;
1367 } else {
1368 _numberInt = -v - 1;
1369 }
1370 }
1371 break;
1372 case 3:
1373
1374 {
1375 long l = _decode64Bits();
1376 if (l >= 0L) {
1377 _numberLong = l;
1378 _numTypesValid = NR_LONG;
1379 } else {
1380 _numberBigInt = _bigNegative(l);
1381 _numTypesValid = NR_BIGINT;
1382 }
1383 }
1384 break;
1385 default:
1386 _invalidToken(ch);
1387 }
1388 }
1389 _currToken = JsonToken.VALUE_NUMBER_INT;
1390 return null;
1391
1392 case 2:
1393 _typeByte = ch;
1394 _tokenIncomplete = true;
1395 _currToken = JsonToken.VALUE_EMBEDDED_OBJECT;
1396 return null;
1397
1398 case 3:
1399 _typeByte = ch;
1400 _tokenIncomplete = true;
1401 _currToken = JsonToken.VALUE_STRING;
1402 return _finishTextToken(ch);
1403
1404 case 4:
1405 _currToken = JsonToken.START_ARRAY;
1406 {
1407 int len = _decodeExplicitLength(lowBits);
1408 _parsingContext = _parsingContext.createChildArrayContext(len);
1409 }
1410 return null;
1411
1412 case 5:
1413 _currToken = JsonToken.START_OBJECT;
1414 {
1415 int len = _decodeExplicitLength(lowBits);
1416 _parsingContext = _parsingContext.createChildObjectContext(len);
1417 }
1418 return null;
1419
1420 case 6:
1421 _reportError("Multiple tags not allowed per value (first tag: "+_tagValue+")");
1422
1423 default:
1424 switch (lowBits) {
1425 case 20:
1426 _currToken = JsonToken.VALUE_FALSE;
1427 return null;
1428 case 21:
1429 _currToken = JsonToken.VALUE_TRUE;
1430 return null;
1431 case 22:
1432 _currToken = JsonToken.VALUE_NULL;
1433 return null;
1434 case 23:
1435 _currToken = _decodeUndefinedValue();
1436 return null;
1437
1438 case 25:
1439
1440 {
1441 _numberFloat = _decodeHalfSizeFloat();
1442 _numTypesValid = NR_FLOAT;
1443 }
1444 _currToken = JsonToken.VALUE_NUMBER_FLOAT;
1445 return null;
1446 case 26:
1447 {
1448 _numberFloat = Float.intBitsToFloat(_decode32Bits());
1449 _numTypesValid = NR_FLOAT;
1450 }
1451 _currToken = JsonToken.VALUE_NUMBER_FLOAT;
1452 return null;
1453 case 27:
1454 _numberDouble = Double.longBitsToDouble(_decode64Bits());
1455 _numTypesValid = NR_DOUBLE;
1456 _currToken = JsonToken.VALUE_NUMBER_FLOAT;
1457 return null;
1458 case 31:
1459 if (_parsingContext.inArray()) {
1460 if (!_parsingContext.hasExpectedLength()) {
1461 _parsingContext = _parsingContext.getParent();
1462 _currToken = JsonToken.END_ARRAY;
1463 return null;
1464 }
1465 }
1466
1467 _reportUnexpectedBreak();
1468 }
1469 _invalidToken(ch);
1470 }
1471
1472 return (nextToken() == JsonToken.VALUE_STRING) ? getText() : null;
1473 }
1474
1475 @Override
1476 public int nextIntValue(int defaultValue) throws IOException
1477 {
1478 if (nextToken() == JsonToken.VALUE_NUMBER_INT) {
1479 return getIntValue();
1480 }
1481 return defaultValue;
1482 }
1483
1484 @Override
1485 public long nextLongValue(long defaultValue) throws IOException
1486 {
1487 if (nextToken() == JsonToken.VALUE_NUMBER_INT) {
1488 return getLongValue();
1489 }
1490 return defaultValue;
1491 }
1492
1493 @Override
1494 public Boolean nextBooleanValue() throws IOException
1495 {
1496 JsonToken t = nextToken();
1497 if (t == JsonToken.VALUE_TRUE) {
1498 return Boolean.TRUE;
1499 }
1500 if (t == JsonToken.VALUE_FALSE) {
1501 return Boolean.FALSE;
1502 }
1503 return null;
1504 }
1505
1506
1511
1512
1518 @Override
1519 public String getText() throws IOException
1520 {
1521 JsonToken t = _currToken;
1522 if (_tokenIncomplete) {
1523 if (t == JsonToken.VALUE_STRING) {
1524 return _finishTextToken(_typeByte);
1525 }
1526 }
1527 if (t == JsonToken.VALUE_STRING) {
1528 return _textBuffer.contentsAsString();
1529 }
1530 if (t == null) {
1531 return null;
1532 }
1533 if (t == JsonToken.FIELD_NAME) {
1534 return _parsingContext.getCurrentName();
1535 }
1536 if (t.isNumeric()) {
1537 return getNumberValue().toString();
1538 }
1539 return _currToken.asString();
1540 }
1541
1542 @Override
1543 public char[] getTextCharacters() throws IOException
1544 {
1545 if (_currToken != null) {
1546 if (_tokenIncomplete) {
1547 _finishToken();
1548 }
1549 if (_currToken == JsonToken.VALUE_STRING) {
1550 return _textBuffer.getTextBuffer();
1551 }
1552 if (_currToken == JsonToken.FIELD_NAME) {
1553 return _parsingContext.getCurrentName().toCharArray();
1554 }
1555 if ((_currToken == JsonToken.VALUE_NUMBER_INT)
1556 || (_currToken == JsonToken.VALUE_NUMBER_FLOAT)) {
1557 return getNumberValue().toString().toCharArray();
1558 }
1559 return _currToken.asCharArray();
1560 }
1561 return null;
1562 }
1563
1564 @Override
1565 public int getTextLength() throws IOException
1566 {
1567 if (_currToken != null) {
1568 if (_tokenIncomplete) {
1569 _finishToken();
1570 }
1571 if (_currToken == JsonToken.VALUE_STRING) {
1572 return _textBuffer.size();
1573 }
1574 if (_currToken == JsonToken.FIELD_NAME) {
1575 return _parsingContext.getCurrentName().length();
1576 }
1577 if ((_currToken == JsonToken.VALUE_NUMBER_INT)
1578 || (_currToken == JsonToken.VALUE_NUMBER_FLOAT)) {
1579 return getNumberValue().toString().length();
1580 }
1581 return _currToken.asCharArray().length;
1582 }
1583 return 0;
1584 }
1585
1586 @Override
1587 public int getTextOffset() throws IOException {
1588 return 0;
1589 }
1590
1591 @Override
1592 public String getValueAsString() throws IOException
1593 {
1594
1595 if (_tokenIncomplete) {
1596 if (_currToken == JsonToken.VALUE_STRING) {
1597 return _finishTextToken(_typeByte);
1598 }
1599 }
1600 if (_currToken == JsonToken.VALUE_STRING) {
1601 return _textBuffer.contentsAsString();
1602 }
1603 if (_currToken == null || _currToken == JsonToken.VALUE_NULL || !_currToken.isScalarValue()) {
1604 return null;
1605 }
1606 return getText();
1607 }
1608
1609 @Override
1610 public String getValueAsString(String defaultValue) throws IOException
1611 {
1612 if (_currToken != JsonToken.VALUE_STRING) {
1613 if (_currToken == null || _currToken == JsonToken.VALUE_NULL || !_currToken.isScalarValue()) {
1614 return defaultValue;
1615 }
1616 }
1617 return getText();
1618 }
1619
1620 @Override
1621 public int getText(Writer writer) throws IOException
1622 {
1623 if (_tokenIncomplete) {
1624 _finishToken();
1625 }
1626 JsonToken t = _currToken;
1627 if (t == JsonToken.VALUE_STRING) {
1628 return _textBuffer.contentsToWriter(writer);
1629 }
1630 if (t == JsonToken.FIELD_NAME) {
1631 String n = _parsingContext.getCurrentName();
1632 writer.write(n);
1633 return n.length();
1634 }
1635 if (t != null) {
1636 if (t.isNumeric()) {
1637 return _textBuffer.contentsToWriter(writer);
1638 }
1639 char[] ch = t.asCharArray();
1640 writer.write(ch);
1641 return ch.length;
1642 }
1643 return 0;
1644 }
1645
1646
1651
1652 @Override
1653 public byte[] getBinaryValue(Base64Variant b64variant) throws IOException
1654 {
1655 if (_tokenIncomplete) {
1656 _finishToken();
1657 }
1658 if (_currToken != JsonToken.VALUE_EMBEDDED_OBJECT ) {
1659
1660 _reportError("Current token ("+currentToken()+") not VALUE_EMBEDDED_OBJECT, can not access as binary");
1661 }
1662 return _binaryValue;
1663 }
1664
1665 @Override
1666 public Object getEmbeddedObject() throws IOException
1667 {
1668 if (_tokenIncomplete) {
1669 _finishToken();
1670 }
1671 if (_currToken == JsonToken.VALUE_EMBEDDED_OBJECT ) {
1672 return _binaryValue;
1673 }
1674 return null;
1675 }
1676
1677 @Override
1678 public int readBinaryValue(Base64Variant b64variant, OutputStream out) throws IOException
1679 {
1680 if (_currToken != JsonToken.VALUE_EMBEDDED_OBJECT ) {
1681
1682 _reportError("Current token ("+currentToken()+") not VALUE_EMBEDDED_OBJECT, can not access as binary");
1683 }
1684 if (!_tokenIncomplete) {
1685 if (_binaryValue == null) {
1686 return 0;
1687 }
1688 final int len = _binaryValue.length;
1689 out.write(_binaryValue, 0, len);
1690 return len;
1691 }
1692
1693 _tokenIncomplete = false;
1694 int len = _decodeExplicitLength(_typeByte & 0x1F);
1695 if (len >= 0) {
1696 return _readAndWriteBytes(out, len);
1697 }
1698
1699 int total = 0;
1700 while (true) {
1701 len = _decodeChunkLength(CBORConstants.MAJOR_TYPE_BYTES);
1702 if (len < 0) {
1703 return total;
1704 }
1705 total += _readAndWriteBytes(out, len);
1706 }
1707 }
1708
1709 private int _readAndWriteBytes(OutputStream out, int total) throws IOException
1710 {
1711 int left = total;
1712 while (left > 0) {
1713 int avail = _inputEnd - _inputPtr;
1714 if (_inputPtr >= _inputEnd) {
1715 loadMoreGuaranteed();
1716 avail = _inputEnd - _inputPtr;
1717 }
1718 int count = Math.min(avail, left);
1719 out.write(_inputBuffer, _inputPtr, count);
1720 _inputPtr += count;
1721 left -= count;
1722 }
1723 _tokenIncomplete = false;
1724 return total;
1725 }
1726
1727
1732
1733 @Override
1734 public boolean isNaN() {
1735 if (_currToken == JsonToken.VALUE_NUMBER_FLOAT) {
1736 if ((_numTypesValid & NR_DOUBLE) != 0) {
1737
1738 double d = _numberDouble;
1739 return Double.isNaN(d) || Double.isInfinite(d);
1740 }
1741 if ((_numTypesValid & NR_FLOAT) != 0) {
1742 float f = _numberFloat;
1743 return Float.isNaN(f) || Float.isInfinite(f);
1744 }
1745 }
1746 return false;
1747 }
1748
1749 @Override
1750 public Number getNumberValue() throws IOException
1751 {
1752 if (_numTypesValid == NR_UNKNOWN) {
1753 _checkNumericValue(NR_UNKNOWN);
1754 }
1755
1756 if (_currToken == JsonToken.VALUE_NUMBER_INT) {
1757 if ((_numTypesValid & NR_INT) != 0) {
1758 return _numberInt;
1759 }
1760 if ((_numTypesValid & NR_LONG) != 0) {
1761 return _numberLong;
1762 }
1763 if ((_numTypesValid & NR_BIGINT) != 0) {
1764 return _numberBigInt;
1765 }
1766
1767 return _numberBigDecimal;
1768 }
1769
1770
1771
1772 if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1773 return _numberBigDecimal;
1774 }
1775 if ((_numTypesValid & NR_DOUBLE) != 0) {
1776 return _numberDouble;
1777 }
1778 if ((_numTypesValid & NR_FLOAT) == 0) {
1779 _throwInternal();
1780 }
1781 return _numberFloat;
1782 }
1783
1784 @Override
1785 public NumberType getNumberType() throws IOException
1786 {
1787 if (_numTypesValid == NR_UNKNOWN) {
1788 _checkNumericValue(NR_UNKNOWN);
1789 }
1790 if (_currToken == JsonToken.VALUE_NUMBER_INT) {
1791 if ((_numTypesValid & NR_INT) != 0) {
1792 return NumberType.INT;
1793 }
1794 if ((_numTypesValid & NR_LONG) != 0) {
1795 return NumberType.LONG;
1796 }
1797 return NumberType.BIG_INTEGER;
1798 }
1799
1800
1806 if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1807 return NumberType.BIG_DECIMAL;
1808 }
1809 if ((_numTypesValid & NR_DOUBLE) != 0) {
1810 return NumberType.DOUBLE;
1811 }
1812 return NumberType.FLOAT;
1813 }
1814
1815 @Override
1816 public int getIntValue() throws IOException
1817 {
1818 if ((_numTypesValid & NR_INT) == 0) {
1819 if (_numTypesValid == NR_UNKNOWN) {
1820 _checkNumericValue(NR_INT);
1821 }
1822 if ((_numTypesValid & NR_INT) == 0) {
1823 convertNumberToInt();
1824 }
1825 }
1826 return _numberInt;
1827 }
1828
1829 @Override
1830 public long getLongValue() throws IOException
1831 {
1832 if ((_numTypesValid & NR_LONG) == 0) {
1833 if (_numTypesValid == NR_UNKNOWN) {
1834 _checkNumericValue(NR_LONG);
1835 }
1836 if ((_numTypesValid & NR_LONG) == 0) {
1837 convertNumberToLong();
1838 }
1839 }
1840 return _numberLong;
1841 }
1842
1843 @Override
1844 public BigInteger getBigIntegerValue() throws IOException
1845 {
1846 if ((_numTypesValid & NR_BIGINT) == 0) {
1847 if (_numTypesValid == NR_UNKNOWN) {
1848 _checkNumericValue(NR_BIGINT);
1849 }
1850 if ((_numTypesValid & NR_BIGINT) == 0) {
1851 convertNumberToBigInteger();
1852 }
1853 }
1854 return _numberBigInt;
1855 }
1856
1857 @Override
1858 public float getFloatValue() throws IOException
1859 {
1860 if ((_numTypesValid & NR_FLOAT) == 0) {
1861 if (_numTypesValid == NR_UNKNOWN) {
1862 _checkNumericValue(NR_FLOAT);
1863 }
1864 if ((_numTypesValid & NR_FLOAT) == 0) {
1865 convertNumberToFloat();
1866 }
1867 }
1868
1869
1874 return _numberFloat;
1875 }
1876
1877 @Override
1878 public double getDoubleValue() throws IOException
1879 {
1880 if ((_numTypesValid & NR_DOUBLE) == 0) {
1881 if (_numTypesValid == NR_UNKNOWN) {
1882 _checkNumericValue(NR_DOUBLE);
1883 }
1884 if ((_numTypesValid & NR_DOUBLE) == 0) {
1885 convertNumberToDouble();
1886 }
1887 }
1888 return _numberDouble;
1889 }
1890
1891 @Override
1892 public BigDecimal getDecimalValue() throws IOException
1893 {
1894 if ((_numTypesValid & NR_BIGDECIMAL) == 0) {
1895 if (_numTypesValid == NR_UNKNOWN) {
1896 _checkNumericValue(NR_BIGDECIMAL);
1897 }
1898 if ((_numTypesValid & NR_BIGDECIMAL) == 0) {
1899 convertNumberToBigDecimal();
1900 }
1901 }
1902 return _numberBigDecimal;
1903 }
1904
1905
1910
1911 protected void _checkNumericValue(int expType) throws IOException
1912 {
1913
1914 if (_currToken == JsonToken.VALUE_NUMBER_INT || _currToken == JsonToken.VALUE_NUMBER_FLOAT) {
1915 return;
1916 }
1917 _reportError("Current token ("+currentToken()+") not numeric, can not use numeric value accessors");
1918 }
1919
1920 protected void convertNumberToInt() throws IOException
1921 {
1922
1923 if ((_numTypesValid & NR_LONG) != 0) {
1924
1925 int result = (int) _numberLong;
1926 if (((long) result) != _numberLong) {
1927 _reportError("Numeric value ("+getText()+") out of range of int");
1928 }
1929 _numberInt = result;
1930 } else if ((_numTypesValid & NR_BIGINT) != 0) {
1931 if (BI_MIN_INT.compareTo(_numberBigInt) > 0
1932 || BI_MAX_INT.compareTo(_numberBigInt) < 0) {
1933 reportOverflowInt();
1934 }
1935 _numberInt = _numberBigInt.intValue();
1936 } else if ((_numTypesValid & NR_DOUBLE) != 0) {
1937
1938 if (_numberDouble < MIN_INT_D || _numberDouble > MAX_INT_D) {
1939 reportOverflowInt();
1940 }
1941 _numberInt = (int) _numberDouble;
1942 } else if ((_numTypesValid & NR_FLOAT) != 0) {
1943 if (_numberFloat < MIN_INT_D || _numberFloat > MAX_INT_D) {
1944 reportOverflowInt();
1945 }
1946 _numberInt = (int) _numberFloat;
1947 } else if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1948 if (BD_MIN_INT.compareTo(_numberBigDecimal) > 0
1949 || BD_MAX_INT.compareTo(_numberBigDecimal) < 0) {
1950 reportOverflowInt();
1951 }
1952 _numberInt = _numberBigDecimal.intValue();
1953 } else {
1954 _throwInternal();
1955 }
1956 _numTypesValid |= NR_INT;
1957 }
1958
1959 protected void convertNumberToLong() throws IOException
1960 {
1961 if ((_numTypesValid & NR_INT) != 0) {
1962 _numberLong = (long) _numberInt;
1963 } else if ((_numTypesValid & NR_BIGINT) != 0) {
1964 if (BI_MIN_LONG.compareTo(_numberBigInt) > 0
1965 || BI_MAX_LONG.compareTo(_numberBigInt) < 0) {
1966 reportOverflowLong();
1967 }
1968 _numberLong = _numberBigInt.longValue();
1969 } else if ((_numTypesValid & NR_DOUBLE) != 0) {
1970 if (_numberDouble < MIN_LONG_D || _numberDouble > MAX_LONG_D) {
1971 reportOverflowLong();
1972 }
1973 _numberLong = (long) _numberDouble;
1974 } else if ((_numTypesValid & NR_FLOAT) != 0) {
1975 if (_numberFloat < MIN_LONG_D || _numberFloat > MAX_LONG_D) {
1976 reportOverflowInt();
1977 }
1978 _numberLong = (long) _numberFloat;
1979 } else if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1980 if (BD_MIN_LONG.compareTo(_numberBigDecimal) > 0
1981 || BD_MAX_LONG.compareTo(_numberBigDecimal) < 0) {
1982 reportOverflowLong();
1983 }
1984 _numberLong = _numberBigDecimal.longValue();
1985 } else {
1986 _throwInternal();
1987 }
1988 _numTypesValid |= NR_LONG;
1989 }
1990
1991 protected void convertNumberToBigInteger() throws IOException
1992 {
1993 if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
1994
1995 _numberBigInt = _numberBigDecimal.toBigInteger();
1996 } else if ((_numTypesValid & NR_LONG) != 0) {
1997 _numberBigInt = BigInteger.valueOf(_numberLong);
1998 } else if ((_numTypesValid & NR_INT) != 0) {
1999 _numberBigInt = BigInteger.valueOf(_numberInt);
2000 } else if ((_numTypesValid & NR_DOUBLE) != 0) {
2001 _numberBigInt = BigDecimal.valueOf(_numberDouble).toBigInteger();
2002 } else if ((_numTypesValid & NR_FLOAT) != 0) {
2003 _numberBigInt = BigDecimal.valueOf(_numberFloat).toBigInteger();
2004 } else {
2005 _throwInternal();
2006 }
2007 _numTypesValid |= NR_BIGINT;
2008 }
2009
2010 protected void convertNumberToFloat() throws IOException
2011 {
2012
2013
2014 if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
2015 _numberFloat = _numberBigDecimal.floatValue();
2016 } else if ((_numTypesValid & NR_BIGINT) != 0) {
2017 _numberFloat = _numberBigInt.floatValue();
2018 } else if ((_numTypesValid & NR_DOUBLE) != 0) {
2019 _numberFloat = (float) _numberDouble;
2020 } else if ((_numTypesValid & NR_LONG) != 0) {
2021 _numberFloat = (float) _numberLong;
2022 } else if ((_numTypesValid & NR_INT) != 0) {
2023 _numberFloat = (float) _numberInt;
2024 } else {
2025 _throwInternal();
2026 }
2027 _numTypesValid |= NR_FLOAT;
2028 }
2029
2030 protected void convertNumberToDouble() throws IOException
2031 {
2032
2033
2034 if ((_numTypesValid & NR_BIGDECIMAL) != 0) {
2035 _numberDouble = _numberBigDecimal.doubleValue();
2036 } else if ((_numTypesValid & NR_FLOAT) != 0) {
2037 _numberDouble = (double) _numberFloat;
2038 } else if ((_numTypesValid & NR_BIGINT) != 0) {
2039 _numberDouble = _numberBigInt.doubleValue();
2040 } else if ((_numTypesValid & NR_LONG) != 0) {
2041 _numberDouble = (double) _numberLong;
2042 } else if ((_numTypesValid & NR_INT) != 0) {
2043 _numberDouble = (double) _numberInt;
2044 } else {
2045 _throwInternal();
2046 }
2047 _numTypesValid |= NR_DOUBLE;
2048 }
2049
2050 protected void convertNumberToBigDecimal() throws IOException
2051 {
2052
2053
2054 if ((_numTypesValid & (NR_DOUBLE | NR_FLOAT)) != 0) {
2055
2056
2057 _numberBigDecimal = NumberInput.parseBigDecimal(getText());
2058 } else if ((_numTypesValid & NR_BIGINT) != 0) {
2059 _numberBigDecimal = new BigDecimal(_numberBigInt);
2060 } else if ((_numTypesValid & NR_LONG) != 0) {
2061 _numberBigDecimal = BigDecimal.valueOf(_numberLong);
2062 } else if ((_numTypesValid & NR_INT) != 0) {
2063 _numberBigDecimal = BigDecimal.valueOf(_numberInt);
2064 } else {
2065 _throwInternal();
2066 }
2067 _numTypesValid |= NR_BIGDECIMAL;
2068 }
2069
2070
2075
2076
2080 protected void _finishToken() throws IOException
2081 {
2082 _tokenIncomplete = false;
2083 int ch = _typeByte;
2084 final int type = ((ch >> 5) & 0x7);
2085 ch &= 0x1F;
2086
2087
2088 if (type != CBORConstants.MAJOR_TYPE_TEXT) {
2089 if (type == CBORConstants.MAJOR_TYPE_BYTES) {
2090 _binaryValue = _finishBytes(_decodeExplicitLength(ch));
2091 return;
2092 }
2093
2094 _throwInternal();
2095 }
2096
2097
2098 final int len = _decodeExplicitLength(ch);
2099
2100 if (len <= 0) {
2101 if (len < 0) {
2102 _finishChunkedText();
2103 } else {
2104 _textBuffer.resetWithEmpty();
2105 }
2106 return;
2107 }
2108 if (len > (_inputEnd - _inputPtr)) {
2109
2110 if (len >= _inputBuffer.length) {
2111
2112 _finishLongText(len);
2113 return;
2114 }
2115 _loadToHaveAtLeast(len);
2116 }
2117
2118 _finishShortText(len);
2119 }
2120
2121
2124 protected String _finishTextToken(int ch) throws IOException
2125 {
2126 _tokenIncomplete = false;
2127 final int type = ((ch >> 5) & 0x7);
2128 ch &= 0x1F;
2129
2130
2131 if (type != CBORConstants.MAJOR_TYPE_TEXT) {
2132
2133 _throwInternal();
2134 }
2135
2136
2137 final int len = _decodeExplicitLength(ch);
2138
2139 if (len <= 0) {
2140 if (len == 0) {
2141 _textBuffer.resetWithEmpty();
2142 return "";
2143 }
2144 _finishChunkedText();
2145 return _textBuffer.contentsAsString();
2146 }
2147 if (len > (_inputEnd - _inputPtr)) {
2148
2149 if (len >= _inputBuffer.length) {
2150
2151 _finishLongText(len);
2152 return _textBuffer.contentsAsString();
2153 }
2154 _loadToHaveAtLeast(len);
2155 }
2156
2157 return _finishShortText(len);
2158 }
2159
2160 private final String _finishShortText(int len) throws IOException
2161 {
2162 char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
2163 if (outBuf.length < len) {
2164 outBuf = _textBuffer.expandCurrentSegment(len);
2165 }
2166
2167 int outPtr = 0;
2168 int inPtr = _inputPtr;
2169 _inputPtr += len;
2170 final byte[] inputBuf = _inputBuffer;
2171
2172
2173 final int end = inPtr + len;
2174
2175 int i;
2176 while ((i = inputBuf[inPtr]) >= 0) {
2177 outBuf[outPtr++] = (char) i;
2178 if (++inPtr == end) {
2179 return _textBuffer.setCurrentAndReturn(outPtr);
2180 }
2181 }
2182
2183 final int[] codes = UTF8_UNIT_CODES;
2184 do {
2185 i = inputBuf[inPtr++] & 0xFF;
2186 switch (codes[i]) {
2187 case 0:
2188 break;
2189 case 1:
2190 i = ((i & 0x1F) << 6) | (inputBuf[inPtr++] & 0x3F);
2191 break;
2192 case 2:
2193 i = ((i & 0x0F) << 12)
2194 | ((inputBuf[inPtr++] & 0x3F) << 6)
2195 | (inputBuf[inPtr++] & 0x3F);
2196 break;
2197 case 3:
2198 i = ((i & 0x07) << 18)
2199 | ((inputBuf[inPtr++] & 0x3F) << 12)
2200 | ((inputBuf[inPtr++] & 0x3F) << 6)
2201 | (inputBuf[inPtr++] & 0x3F);
2202
2203 i -= 0x10000;
2204 outBuf[outPtr++] = (char) (0xD800 | (i >> 10));
2205 i = 0xDC00 | (i & 0x3FF);
2206 break;
2207 default:
2208 _reportError("Invalid byte "+Integer.toHexString(i)+" in Unicode text block");
2209 }
2210 outBuf[outPtr++] = (char) i;
2211 } while (inPtr < end);
2212 return _textBuffer.setCurrentAndReturn(outPtr);
2213 }
2214
2215 private final void _finishLongText(int len) throws IOException
2216 {
2217 char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
2218 int outPtr = 0;
2219 final int[] codes = UTF8_UNIT_CODES;
2220 int outEnd = outBuf.length;
2221
2222 while (--len >= 0) {
2223 int c = _nextByte() & 0xFF;
2224 int code = codes[c];
2225 if (code == 0 && outPtr < outEnd) {
2226 outBuf[outPtr++] = (char) c;
2227 continue;
2228 }
2229 if ((len -= code) < 0) {
2230 throw _constructError("Malformed UTF-8 character at end of long (non-chunked) text segment");
2231 }
2232
2233 switch (code) {
2234 case 0:
2235 break;
2236 case 1:
2237 {
2238 int d = _nextByte();
2239 if ((d & 0xC0) != 0x080) {
2240 _reportInvalidOther(d & 0xFF, _inputPtr);
2241 }
2242 c = ((c & 0x1F) << 6) | (d & 0x3F);
2243 }
2244 break;
2245 case 2:
2246 c = _decodeUTF8_3(c);
2247 break;
2248 case 3:
2249 c = _decodeUTF8_4(c);
2250
2251 outBuf[outPtr++] = (char) (0xD800 | (c >> 10));
2252 if (outPtr >= outBuf.length) {
2253 outBuf = _textBuffer.finishCurrentSegment();
2254 outPtr = 0;
2255 outEnd = outBuf.length;
2256 }
2257 c = 0xDC00 | (c & 0x3FF);
2258
2259 break;
2260 default:
2261
2262 _reportInvalidChar(c);
2263 }
2264
2265 if (outPtr >= outEnd) {
2266 outBuf = _textBuffer.finishCurrentSegment();
2267 outPtr = 0;
2268 outEnd = outBuf.length;
2269 }
2270
2271 outBuf[outPtr++] = (char) c;
2272 }
2273 _textBuffer.setCurrentLength(outPtr);
2274 }
2275
2276 private final void _finishChunkedText() throws IOException
2277 {
2278 char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
2279 int outPtr = 0;
2280 final int[] codes = UTF8_UNIT_CODES;
2281 int outEnd = outBuf.length;
2282 final byte[] input = _inputBuffer;
2283
2284 _chunkEnd = _inputPtr;
2285 _chunkLeft = 0;
2286
2287 while (true) {
2288
2289 if (_inputPtr >= _chunkEnd) {
2290
2291 if (_chunkLeft == 0) {
2292 int len = _decodeChunkLength(CBORConstants.MAJOR_TYPE_TEXT);
2293 if (len < 0) {
2294 break;
2295 }
2296 _chunkLeft = len;
2297 int end = _inputPtr + len;
2298 if (end <= _inputEnd) {
2299 _chunkLeft = 0;
2300 _chunkEnd = end;
2301 } else {
2302 _chunkLeft = (end - _inputEnd);
2303 _chunkEnd = _inputEnd;
2304 }
2305 }
2306
2307 if (_inputPtr >= _inputEnd) {
2308 loadMoreGuaranteed();
2309 int end = _inputPtr + _chunkLeft;
2310 if (end <= _inputEnd) {
2311 _chunkLeft = 0;
2312 _chunkEnd = end;
2313 } else {
2314 _chunkLeft = (end - _inputEnd);
2315 _chunkEnd = _inputEnd;
2316 }
2317 }
2318 }
2319 int c = input[_inputPtr++] & 0xFF;
2320 int code = codes[c];
2321 if (code == 0 && outPtr < outEnd) {
2322 outBuf[outPtr++] = (char) c;
2323 continue;
2324 }
2325 switch (code) {
2326 case 0:
2327 break;
2328 case 1:
2329 {
2330 int d = _nextChunkedByte();
2331 if ((d & 0xC0) != 0x080) {
2332 _reportInvalidOther(d & 0xFF, _inputPtr);
2333 }
2334 c = ((c & 0x1F) << 6) | (d & 0x3F);
2335 }
2336 break;
2337 case 2:
2338 c = _decodeChunkedUTF8_3(c);
2339 break;
2340 case 3:
2341 c = _decodeChunkedUTF8_4(c);
2342
2343 if (outPtr >= outBuf.length) {
2344 outBuf = _textBuffer.finishCurrentSegment();
2345 outPtr = 0;
2346 outEnd = outBuf.length;
2347 }
2348 outBuf[outPtr++] = (char) (0xD800 | (c >> 10));
2349 c = 0xDC00 | (c & 0x3FF);
2350
2351 break;
2352 default:
2353
2354 _reportInvalidChar(c);
2355 }
2356
2357 if (outPtr >= outEnd) {
2358 outBuf = _textBuffer.finishCurrentSegment();
2359 outPtr = 0;
2360 outEnd = outBuf.length;
2361 }
2362
2363 outBuf[outPtr++] = (char) c;
2364 }
2365 _textBuffer.setCurrentLength(outPtr);
2366 }
2367
2368 private final int _nextByte() throws IOException {
2369 int inPtr = _inputPtr;
2370 if (inPtr < _inputEnd) {
2371 int ch = _inputBuffer[inPtr];
2372 _inputPtr = inPtr+1;
2373 return ch;
2374 }
2375 loadMoreGuaranteed();
2376 return _inputBuffer[_inputPtr++];
2377 }
2378
2379 private final int _nextChunkedByte() throws IOException {
2380 int inPtr = _inputPtr;
2381
2382
2383 if (inPtr >= _chunkEnd) {
2384 return _nextChunkedByte2();
2385 }
2386 int ch = _inputBuffer[inPtr];
2387 _inputPtr = inPtr+1;
2388 return ch;
2389 }
2390
2391 private final int _nextChunkedByte2() throws IOException
2392 {
2393
2394
2395
2396 if (_inputPtr >= _inputEnd) {
2397 loadMoreGuaranteed();
2398 if (_chunkLeft > 0) {
2399 int end = _inputPtr + _chunkLeft;
2400 if (end <= _inputEnd) {
2401 _chunkLeft = 0;
2402 _chunkEnd = end;
2403 } else {
2404 _chunkLeft = (end - _inputEnd);
2405 _chunkEnd = _inputEnd;
2406 }
2407
2408 return _inputBuffer[_inputPtr++];
2409 }
2410 }
2411 int len = _decodeChunkLength(CBORConstants.MAJOR_TYPE_TEXT);
2412
2413 if (len < 0) {
2414 _reportInvalidEOF(": chunked Text ends with partial UTF-8 character",
2415 JsonToken.VALUE_STRING);
2416 }
2417 int end = _inputPtr + len;
2418 if (end <= _inputEnd) {
2419 _chunkLeft = 0;
2420 _chunkEnd = end;
2421 } else {
2422 _chunkLeft = (end - _inputEnd);
2423 _chunkEnd = _inputEnd;
2424 }
2425
2426 return _inputBuffer[_inputPtr++];
2427 }
2428
2429 @SuppressWarnings("resource")
2430 protected byte[] _finishBytes(int len) throws IOException
2431 {
2432
2433 if (len >= 0) {
2434 if (len == 0) {
2435 return NO_BYTES;
2436 }
2437 byte[] b = new byte[len];
2438 if (_inputPtr >= _inputEnd) {
2439 loadMoreGuaranteed();
2440 }
2441 int ptr = 0;
2442 while (true) {
2443 int toAdd = Math.min(len, _inputEnd - _inputPtr);
2444 System.arraycopy(_inputBuffer, _inputPtr, b, ptr, toAdd);
2445 _inputPtr += toAdd;
2446 ptr += toAdd;
2447 len -= toAdd;
2448 if (len <= 0) {
2449 return b;
2450 }
2451 loadMoreGuaranteed();
2452 }
2453 }
2454
2455
2456 ByteArrayBuilder bb = _getByteArrayBuilder();
2457 while (true) {
2458 if (_inputPtr >= _inputEnd) {
2459 loadMoreGuaranteed();
2460 }
2461 int ch = _inputBuffer[_inputPtr++] & 0xFF;
2462 if (ch == 0xFF) {
2463 break;
2464 }
2465
2466 int type = (ch >> 5);
2467 if (type != CBORConstants.MAJOR_TYPE_BYTES) {
2468 throw _constructError("Mismatched chunk in chunked content: expected "+CBORConstants.MAJOR_TYPE_BYTES
2469 +" but encountered "+type);
2470 }
2471 len = _decodeExplicitLength(ch & 0x1F);
2472 if (len < 0) {
2473 throw _constructError("Illegal chunked-length indicator within chunked-length value (type "+CBORConstants.MAJOR_TYPE_BYTES+")");
2474 }
2475 while (len > 0) {
2476 int avail = _inputEnd - _inputPtr;
2477 if (_inputPtr >= _inputEnd) {
2478 loadMoreGuaranteed();
2479 avail = _inputEnd - _inputPtr;
2480 }
2481 int count = Math.min(avail, len);
2482 bb.write(_inputBuffer, _inputPtr, count);
2483 _inputPtr += count;
2484 len -= count;
2485 }
2486 }
2487 return bb.toByteArray();
2488 }
2489
2490 protected final JsonToken _decodeFieldName() throws IOException
2491 {
2492 if (_inputPtr >= _inputEnd) {
2493 loadMoreGuaranteed();
2494 }
2495 final int ch = _inputBuffer[_inputPtr++];
2496 final int type = ((ch >> 5) & 0x7);
2497
2498
2499 if (type != CBORConstants.MAJOR_TYPE_TEXT) {
2500 if (ch == -1) {
2501 if (!_parsingContext.hasExpectedLength()) {
2502 _parsingContext = _parsingContext.getParent();
2503 return JsonToken.END_OBJECT;
2504 }
2505 _reportUnexpectedBreak();
2506 }
2507
2508 _decodeNonStringName(ch);
2509 return JsonToken.FIELD_NAME;
2510 }
2511 final int lenMarker = ch & 0x1F;
2512 String name;
2513 if (lenMarker <= 23) {
2514 if (lenMarker == 0) {
2515 name = "";
2516 } else {
2517 name = _findDecodedFromSymbols(lenMarker);
2518 if (name != null) {
2519 _inputPtr += lenMarker;
2520 } else {
2521 name = _decodeShortName(lenMarker);
2522 name = _addDecodedToSymbols(lenMarker, name);
2523 }
2524 }
2525 } else {
2526 final int actualLen = _decodeExplicitLength(lenMarker);
2527 if (actualLen < 0) {
2528 name = _decodeChunkedName();
2529 } else {
2530 name = _decodeLongerName(actualLen);
2531 }
2532 }
2533 _parsingContext.setCurrentName(name);
2534 return JsonToken.FIELD_NAME;
2535 }
2536
2537 private final String _decodeShortName(int len) throws IOException
2538 {
2539
2540 int outPtr = 0;
2541 char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
2542 if (outBuf.length < len) {
2543 outBuf = _textBuffer.expandCurrentSegment(len);
2544 }
2545 int inPtr = _inputPtr;
2546 _inputPtr += len;
2547 final int[] codes = UTF8_UNIT_CODES;
2548 final byte[] inBuf = _inputBuffer;
2549
2550
2551 final int end = inPtr + len;
2552 while (true) {
2553 int i = inBuf[inPtr] & 0xFF;
2554 int code = codes[i];
2555 if (code != 0) {
2556 break;
2557 }
2558 outBuf[outPtr++] = (char) i;
2559 if (++inPtr == end) {
2560 return _textBuffer.setCurrentAndReturn(outPtr);
2561 }
2562 }
2563
2564
2565 while (inPtr < end) {
2566 int i = inBuf[inPtr++] & 0xFF;
2567 int code = codes[i];
2568 if (code != 0) {
2569
2570 switch (code) {
2571 case 1:
2572 i = ((i & 0x1F) << 6) | (inBuf[inPtr++] & 0x3F);
2573 break;
2574 case 2:
2575 i = ((i & 0x0F) << 12)
2576 | ((inBuf[inPtr++] & 0x3F) << 6)
2577 | (inBuf[inPtr++] & 0x3F);
2578 break;
2579 case 3:
2580 i = ((i & 0x07) << 18)
2581 | ((inBuf[inPtr++] & 0x3F) << 12)
2582 | ((inBuf[inPtr++] & 0x3F) << 6)
2583 | (inBuf[inPtr++] & 0x3F);
2584
2585 i -= 0x10000;
2586 outBuf[outPtr++] = (char) (0xD800 | (i >> 10));
2587 i = 0xDC00 | (i & 0x3FF);
2588 break;
2589 default:
2590 _reportError("Invalid byte "+Integer.toHexString(i)+" in Object name");
2591 }
2592 }
2593 outBuf[outPtr++] = (char) i;
2594 }
2595 return _textBuffer.setCurrentAndReturn(outPtr);
2596 }
2597
2598 private final String _decodeLongerName(int len) throws IOException
2599 {
2600
2601 if ((_inputEnd - _inputPtr) < len) {
2602
2603 if (len >= _inputBuffer.length) {
2604
2605 _finishLongText(len);
2606 return _textBuffer.contentsAsString();
2607 }
2608 _loadToHaveAtLeast(len);
2609 }
2610 String name = _findDecodedFromSymbols(len);
2611 if (name != null) {
2612 _inputPtr += len;
2613 return name;
2614 }
2615 name = _decodeShortName(len);
2616 return _addDecodedToSymbols(len, name);
2617 }
2618
2619 private final String _decodeChunkedName() throws IOException
2620 {
2621 _finishChunkedText();
2622 return _textBuffer.contentsAsString();
2623 }
2624
2625
2629 protected final void _decodeNonStringName(int ch) throws IOException
2630 {
2631 final int type = ((ch >> 5) & 0x7);
2632 String name;
2633 if (type == CBORConstants.MAJOR_TYPE_INT_POS) {
2634 name = _numberToName(ch, false);
2635 } else if (type == CBORConstants.MAJOR_TYPE_INT_NEG) {
2636 name = _numberToName(ch, true);
2637 } else if (type == CBORConstants.MAJOR_TYPE_BYTES) {
2638
2641 final int blen = _decodeExplicitLength(ch & 0x1F);
2642 byte[] b = _finishBytes(blen);
2643
2644
2645 name = new String(b, UTF8);
2646 } else {
2647 if ((ch & 0xFF) == CBORConstants.INT_BREAK) {
2648 _reportUnexpectedBreak();
2649 }
2650 throw _constructError("Unsupported major type ("+type+") for CBOR Objects, not (yet?) supported, only Strings");
2651 }
2652 _parsingContext.setCurrentName(name);
2653 }
2654
2655 private final String _findDecodedFromSymbols(final int len) throws IOException
2656 {
2657 if ((_inputEnd - _inputPtr) < len) {
2658 _loadToHaveAtLeast(len);
2659 }
2660
2661 if (len < 5) {
2662 int inPtr = _inputPtr;
2663 final byte[] inBuf = _inputBuffer;
2664 int q = inBuf[inPtr] & 0xFF;
2665 if (len > 1) {
2666 q = (q << 8) + (inBuf[++inPtr] & 0xFF);
2667 if (len > 2) {
2668 q = (q << 8) + (inBuf[++inPtr] & 0xFF);
2669 if (len > 3) {
2670 q = (q << 8) + (inBuf[++inPtr] & 0xFF);
2671 }
2672 }
2673 }
2674 _quad1 = q;
2675 return _symbols.findName(q);
2676 }
2677
2678 final byte[] inBuf = _inputBuffer;
2679 int inPtr = _inputPtr;
2680
2681
2682 int q1 = (inBuf[inPtr++] & 0xFF);
2683 q1 = (q1 << 8) | (inBuf[inPtr++] & 0xFF);
2684 q1 = (q1 << 8) | (inBuf[inPtr++] & 0xFF);
2685 q1 = (q1 << 8) | (inBuf[inPtr++] & 0xFF);
2686
2687 if (len < 9) {
2688 int q2 = (inBuf[inPtr++] & 0xFF);
2689 int left = len - 5;
2690 if (left > 0) {
2691 q2 = (q2 << 8) + (inBuf[inPtr++] & 0xFF);
2692 if (left > 1) {
2693 q2 = (q2 << 8) + (inBuf[inPtr++] & 0xFF);
2694 if (left > 2) {
2695 q2 = (q2 << 8) + (inBuf[inPtr++] & 0xFF);
2696 }
2697 }
2698 }
2699 _quad1 = q1;
2700 _quad2 = q2;
2701 return _symbols.findName(q1, q2);
2702 }
2703
2704 int q2 = (inBuf[inPtr++] & 0xFF);
2705 q2 = (q2 << 8) | (inBuf[inPtr++] & 0xFF);
2706 q2 = (q2 << 8) | (inBuf[inPtr++] & 0xFF);
2707 q2 = (q2 << 8) | (inBuf[inPtr++] & 0xFF);
2708
2709 if (len < 13) {
2710 int q3 = (inBuf[inPtr++] & 0xFF);
2711 int left = len - 9;
2712 if (left > 0) {
2713 q3 = (q3 << 8) + (inBuf[inPtr++] & 0xFF);
2714 if (left > 1) {
2715 q3 = (q3 << 8) + (inBuf[inPtr++] & 0xFF);
2716 if (left > 2) {
2717 q3 = (q3 << 8) + (inBuf[inPtr++] & 0xFF);
2718 }
2719 }
2720 }
2721 _quad1 = q1;
2722 _quad2 = q2;
2723 _quad3 = q3;
2724 return _symbols.findName(q1, q2, q3);
2725 }
2726 return _findDecodedLong(len, q1, q2);
2727 }
2728
2729
2732 private final String _findDecodedLong(int len, int q1, int q2) throws IOException
2733 {
2734
2735 {
2736 int bufLen = (len + 3) >> 2;
2737 if (bufLen > _quadBuffer.length) {
2738 _quadBuffer = _growArrayTo(_quadBuffer, bufLen);
2739 }
2740 }
2741 _quadBuffer[0] = q1;
2742 _quadBuffer[1] = q2;
2743
2744
2745 int offset = 2;
2746 int inPtr = _inputPtr+8;
2747 len -= 8;
2748
2749 final byte[] inBuf = _inputBuffer;
2750 do {
2751 int q = (inBuf[inPtr++] & 0xFF);
2752 q = (q << 8) | inBuf[inPtr++] & 0xFF;
2753 q = (q << 8) | inBuf[inPtr++] & 0xFF;
2754 q = (q << 8) | inBuf[inPtr++] & 0xFF;
2755 _quadBuffer[offset++] = q;
2756 } while ((len -= 4) > 3);
2757
2758 if (len > 0) {
2759 int q = inBuf[inPtr] & 0xFF;
2760 if (len > 1) {
2761 q = (q << 8) + (inBuf[++inPtr] & 0xFF);
2762 if (len > 2) {
2763 q = (q << 8) + (inBuf[++inPtr] & 0xFF);
2764 }
2765 }
2766 _quadBuffer[offset++] = q;
2767 }
2768 return _symbols.findName(_quadBuffer, offset);
2769 }
2770
2771 private final String _addDecodedToSymbols(int len, String name) {
2772 if (len < 5) {
2773 return _symbols.addName(name, _quad1);
2774 }
2775 if (len < 9) {
2776 return _symbols.addName(name, _quad1, _quad2);
2777 }
2778 if (len < 13) {
2779 return _symbols.addName(name, _quad1, _quad2, _quad3);
2780 }
2781 int qlen = (len + 3) >> 2;
2782 return _symbols.addName(name, _quadBuffer, qlen);
2783 }
2784
2785 private static int[] _growArrayTo(int[] arr, int minSize) {
2786 return Arrays.copyOf(arr, minSize+4);
2787 }
2788
2789
2794
2795
2800 protected void _skipIncomplete() throws IOException
2801 {
2802 _tokenIncomplete = false;
2803 final int type = ((_typeByte >> 5) & 0x7);
2804
2805
2806 if (type != CBORConstants.MAJOR_TYPE_TEXT
2807 && type == CBORConstants.MAJOR_TYPE_TEXT) {
2808 _throwInternal();
2809 }
2810 final int lowBits = _typeByte & 0x1F;
2811
2812 if (lowBits <= 23) {
2813 if (lowBits > 0) {
2814 _skipBytes(lowBits);
2815 }
2816 return;
2817 }
2818 switch (lowBits) {
2819 case 24:
2820 _skipBytes(_decode8Bits());
2821 break;
2822 case 25:
2823 _skipBytes(_decode16Bits());
2824 break;
2825 case 26:
2826 _skipBytes(_decode32Bits());
2827 break;
2828 case 27:
2829 _skipBytesL(_decode64Bits());
2830 break;
2831 case 31:
2832 _skipChunked(type);
2833 break;
2834 default:
2835 _invalidToken(_typeByte);
2836 }
2837 }
2838
2839 protected void _skipChunked(int expectedType) throws IOException
2840 {
2841 while (true) {
2842 if (_inputPtr >= _inputEnd) {
2843 loadMoreGuaranteed();
2844 }
2845 int ch = _inputBuffer[_inputPtr++] & 0xFF;
2846 if (ch == 0xFF) {
2847 return;
2848 }
2849
2850 int type = (ch >> 5);
2851 if (type != expectedType) {
2852 throw _constructError("Mismatched chunk in chunked content: expected "+expectedType
2853 +" but encountered "+type);
2854 }
2855
2856 final int lowBits = ch & 0x1F;
2857
2858 if (lowBits <= 23) {
2859 if (lowBits > 0) {
2860 _skipBytes(lowBits);
2861 }
2862 continue;
2863 }
2864 switch (lowBits) {
2865 case 24:
2866 _skipBytes(_decode8Bits());
2867 break;
2868 case 25:
2869 _skipBytes(_decode16Bits());
2870 break;
2871 case 26:
2872 _skipBytes(_decode32Bits());
2873 break;
2874 case 27:
2875 _skipBytesL(_decode64Bits());
2876 break;
2877 case 31:
2878 throw _constructError("Illegal chunked-length indicator within chunked-length value (type "+expectedType+")");
2879 default:
2880 _invalidToken(_typeByte);
2881 }
2882 }
2883 }
2884
2885 protected void _skipBytesL(long llen) throws IOException
2886 {
2887 while (llen > MAX_INT_L) {
2888 _skipBytes((int) MAX_INT_L);
2889 llen -= MAX_INT_L;
2890 }
2891 _skipBytes((int) llen);
2892 }
2893
2894 protected void _skipBytes(int len) throws IOException
2895 {
2896 while (true) {
2897 int toAdd = Math.min(len, _inputEnd - _inputPtr);
2898 _inputPtr += toAdd;
2899 len -= toAdd;
2900 if (len <= 0) {
2901 return;
2902 }
2903 loadMoreGuaranteed();
2904 }
2905 }
2906
2907
2912
2913 private final int _decodeTag(int lowBits) throws IOException
2914 {
2915 if (lowBits <= 23) {
2916 return lowBits;
2917 }
2918 switch (lowBits - 24) {
2919 case 0:
2920 return _decode8Bits();
2921 case 1:
2922 return _decode16Bits();
2923 case 2:
2924 return _decode32Bits();
2925 case 3:
2926
2927
2928 long l = _decode64Bits();
2929 if (l < MIN_INT_L || l > MAX_INT_L) {
2930 _reportError("Illegal Tag value: "+l);
2931 }
2932 return (int) l;
2933 }
2934 throw _constructError("Invalid low bits for Tag token: 0x"+Integer.toHexString(lowBits));
2935 }
2936
2937
2944 private final int _decodeExplicitLength(int lowBits) throws IOException
2945 {
2946
2947 if (lowBits == 31) {
2948 return -1;
2949 }
2950 if (lowBits <= 23) {
2951 return lowBits;
2952 }
2953 switch (lowBits - 24) {
2954 case 0:
2955 return _decode8Bits();
2956 case 1:
2957 return _decode16Bits();
2958 case 2:
2959 return _decode32Bits();
2960 case 3:
2961 long l = _decode64Bits();
2962 if (l < 0 || l > MAX_INT_L) {
2963 throw _constructError("Illegal length for "+currentToken()+": "+l);
2964 }
2965 return (int) l;
2966 }
2967 throw _constructError("Invalid length for "+currentToken()+": 0x"+Integer.toHexString(lowBits));
2968 }
2969
2970 private int _decodeChunkLength(int expType) throws IOException
2971 {
2972 if (_inputPtr >= _inputEnd) {
2973 loadMoreGuaranteed();
2974 }
2975 int ch = (int) _inputBuffer[_inputPtr++] & 0xFF;
2976 if (ch == CBORConstants.INT_BREAK) {
2977 return -1;
2978 }
2979 int type = (ch >> 5);
2980 if (type != expType) {
2981 throw _constructError("Mismatched chunk in chunked content: expected "
2982 +expType+" but encountered "+type+" (byte 0x"+Integer.toHexString(ch)+")");
2983 }
2984 int len = _decodeExplicitLength(ch & 0x1F);
2985 if (len < 0) {
2986 throw _constructError("Illegal chunked-length indicator within chunked-length value (type "+expType+")");
2987 }
2988 return len;
2989 }
2990
2991 private float _decodeHalfSizeFloat() throws IOException
2992 {
2993 int i16 = _decode16Bits() & 0xFFFF;
2994
2995 boolean neg = (i16 >> 15) != 0;
2996 int e = (i16 >> 10) & 0x1F;
2997 int f = i16 & 0x03FF;
2998
2999 if (e == 0) {
3000 float result = (float) (MATH_POW_2_NEG14 * (f / MATH_POW_2_10));
3001 return neg ? -result : result;
3002 }
3003 if (e == 0x1F) {
3004 if (f != 0) return Float.NaN;
3005 return neg ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
3006 }
3007 float result = (float) (Math.pow(2, e - 15) * (1 + f / MATH_POW_2_10));
3008 return neg ? -result : result;
3009 }
3010
3011 private final int _decode8Bits() throws IOException {
3012 if (_inputPtr >= _inputEnd) {
3013 loadMoreGuaranteed();
3014 }
3015 return _inputBuffer[_inputPtr++] & 0xFF;
3016 }
3017
3018 private final int _decode16Bits() throws IOException {
3019 int ptr = _inputPtr;
3020 if ((ptr + 1) >= _inputEnd) {
3021 return _slow16();
3022 }
3023 final byte[] b = _inputBuffer;
3024 int v = ((b[ptr] & 0xFF) << 8) + (b[ptr+1] & 0xFF);
3025 _inputPtr = ptr+2;
3026 return v;
3027 }
3028
3029 private final int _slow16() throws IOException {
3030 if (_inputPtr >= _inputEnd) {
3031 loadMoreGuaranteed();
3032 }
3033 int v = (_inputBuffer[_inputPtr++] & 0xFF);
3034 if (_inputPtr >= _inputEnd) {
3035 loadMoreGuaranteed();
3036 }
3037 return (v << 8) + (_inputBuffer[_inputPtr++] & 0xFF);
3038 }
3039
3040 private final int _decode32Bits() throws IOException {
3041 int ptr = _inputPtr;
3042 if ((ptr + 3) >= _inputEnd) {
3043 return _slow32();
3044 }
3045 final byte[] b = _inputBuffer;
3046 int v = (b[ptr++] << 24) + ((b[ptr++] & 0xFF) << 16)
3047 + ((b[ptr++] & 0xFF) << 8) + (b[ptr++] & 0xFF);
3048 _inputPtr = ptr;
3049 return v;
3050 }
3051
3052 private final int _slow32() throws IOException {
3053 if (_inputPtr >= _inputEnd) {
3054 loadMoreGuaranteed();
3055 }
3056 int v = _inputBuffer[_inputPtr++];
3057 if (_inputPtr >= _inputEnd) {
3058 loadMoreGuaranteed();
3059 }
3060 v = (v << 8) + (_inputBuffer[_inputPtr++] & 0xFF);
3061 if (_inputPtr >= _inputEnd) {
3062 loadMoreGuaranteed();
3063 }
3064 v = (v << 8) + (_inputBuffer[_inputPtr++] & 0xFF);
3065 if (_inputPtr >= _inputEnd) {
3066 loadMoreGuaranteed();
3067 }
3068 return (v << 8) + (_inputBuffer[_inputPtr++] & 0xFF);
3069 }
3070
3071 private final long _decode64Bits() throws IOException {
3072 int ptr = _inputPtr;
3073 if ((ptr + 7) >= _inputEnd) {
3074 return _slow64();
3075 }
3076 final byte[] b = _inputBuffer;
3077 int i1 = (b[ptr++] << 24) + ((b[ptr++] & 0xFF) << 16)
3078 + ((b[ptr++] & 0xFF) << 8) + (b[ptr++] & 0xFF);
3079 int i2 = (b[ptr++] << 24) + ((b[ptr++] & 0xFF) << 16)
3080 + ((b[ptr++] & 0xFF) << 8) + (b[ptr++] & 0xFF);
3081 _inputPtr = ptr;
3082 return _long(i1, i2);
3083 }
3084
3085 private final long _slow64() throws IOException {
3086 return _long(_decode32Bits(), _decode32Bits());
3087 }
3088
3089 private final static long _long(int i1, int i2)
3090 {
3091 long l1 = i1;
3092 long l2 = i2;
3093 l2 = (l2 << 32) >>> 32;
3094 return (l1 << 32) + l2;
3095 }
3096
3097
3107 protected JsonToken _decodeUndefinedValue() throws IOException {
3108 return JsonToken.VALUE_NULL;
3109 }
3110
3111
3116
3117
3126
3127 private final int _decodeUTF8_3(int c1) throws IOException
3128 {
3129 c1 &= 0x0F;
3130 int d = _nextByte();
3131 if ((d & 0xC0) != 0x080) {
3132 _reportInvalidOther(d & 0xFF, _inputPtr);
3133 }
3134 int c = (c1 << 6) | (d & 0x3F);
3135 d = _nextByte();
3136 if ((d & 0xC0) != 0x080) {
3137 _reportInvalidOther(d & 0xFF, _inputPtr);
3138 }
3139 c = (c << 6) | (d & 0x3F);
3140 return c;
3141 }
3142
3143 private final int _decodeChunkedUTF8_3(int c1) throws IOException
3144 {
3145 c1 &= 0x0F;
3146 int d = _nextChunkedByte();
3147 if ((d & 0xC0) != 0x080) {
3148 _reportInvalidOther(d & 0xFF, _inputPtr);
3149 }
3150 int c = (c1 << 6) | (d & 0x3F);
3151 d = _nextChunkedByte();
3152 if ((d & 0xC0) != 0x080) {
3153 _reportInvalidOther(d & 0xFF, _inputPtr);
3154 }
3155 c = (c << 6) | (d & 0x3F);
3156 return c;
3157 }
3158
3159
3163 private final int _decodeUTF8_4(int c) throws IOException
3164 {
3165 int d = _nextByte();
3166 if ((d & 0xC0) != 0x080) {
3167 _reportInvalidOther(d & 0xFF, _inputPtr);
3168 }
3169 c = ((c & 0x07) << 6) | (d & 0x3F);
3170 d = _nextByte();
3171 if ((d & 0xC0) != 0x080) {
3172 _reportInvalidOther(d & 0xFF, _inputPtr);
3173 }
3174 c = (c << 6) | (d & 0x3F);
3175 d = _nextByte();
3176 if ((d & 0xC0) != 0x080) {
3177 _reportInvalidOther(d & 0xFF, _inputPtr);
3178 }
3179 return ((c << 6) | (d & 0x3F)) - 0x10000;
3180 }
3181
3182 private final int _decodeChunkedUTF8_4(int c) throws IOException
3183 {
3184 int d = _nextChunkedByte();
3185 if ((d & 0xC0) != 0x080) {
3186 _reportInvalidOther(d & 0xFF, _inputPtr);
3187 }
3188 c = ((c & 0x07) << 6) | (d & 0x3F);
3189 d = _nextChunkedByte();
3190 if ((d & 0xC0) != 0x080) {
3191 _reportInvalidOther(d & 0xFF, _inputPtr);
3192 }
3193 c = (c << 6) | (d & 0x3F);
3194 d = _nextChunkedByte();
3195 if ((d & 0xC0) != 0x080) {
3196 _reportInvalidOther(d & 0xFF, _inputPtr);
3197 }
3198 return ((c << 6) | (d & 0x3F)) - 0x10000;
3199 }
3200
3201
3206
3207 protected final boolean loadMore() throws IOException
3208 {
3209 if (_inputStream != null) {
3210 _currInputProcessed += _inputEnd;
3211
3212 int count = _inputStream.read(_inputBuffer, 0, _inputBuffer.length);
3213 if (count > 0) {
3214 _inputPtr = 0;
3215 _inputEnd = count;
3216 return true;
3217 }
3218
3219 _closeInput();
3220
3221 if (count == 0) {
3222 throw new IOException("InputStream.read() returned 0 characters when trying to read "+_inputBuffer.length+" bytes");
3223 }
3224 }
3225 return false;
3226 }
3227
3228 protected final void loadMoreGuaranteed() throws IOException {
3229 if (!loadMore()) { _reportInvalidEOF(); }
3230 }
3231
3232
3236 protected final void _loadToHaveAtLeast(int minAvailable) throws IOException
3237 {
3238
3239 if (_inputStream == null) {
3240 throw _constructError("Needed to read "+minAvailable+" bytes, reached end-of-input");
3241 }
3242
3243 int amount = _inputEnd - _inputPtr;
3244 if (amount > 0 && _inputPtr > 0) {
3245
3246 System.arraycopy(_inputBuffer, _inputPtr, _inputBuffer, 0, amount);
3247 _inputEnd = amount;
3248 } else {
3249 _inputEnd = 0;
3250 }
3251
3252 _currInputProcessed += _inputPtr;
3253 _inputPtr = 0;
3254 while (_inputEnd < minAvailable) {
3255 int count = _inputStream.read(_inputBuffer, _inputEnd, _inputBuffer.length - _inputEnd);
3256 if (count < 1) {
3257
3258 _closeInput();
3259
3260 if (count == 0) {
3261 throw new IOException("InputStream.read() returned 0 characters when trying to read "+amount+" bytes");
3262 }
3263 throw _constructError("Needed to read "+minAvailable+" bytes, missed "+minAvailable+" before end-of-input");
3264 }
3265 _inputEnd += count;
3266 }
3267 }
3268
3269 protected ByteArrayBuilder _getByteArrayBuilder() {
3270 if (_byteArrayBuilder == null) {
3271 _byteArrayBuilder = new ByteArrayBuilder();
3272 } else {
3273 _byteArrayBuilder.reset();
3274 }
3275 return _byteArrayBuilder;
3276 }
3277
3278 @SuppressWarnings("deprecation")
3279 protected void _closeInput() throws IOException {
3280 if (_inputStream != null) {
3281 if (_ioContext.isResourceManaged() || isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)) {
3282 _inputStream.close();
3283 }
3284 _inputStream = null;
3285 }
3286 }
3287
3288 @Override
3289 protected void _handleEOF() throws JsonParseException {
3290 if (!_parsingContext.inRoot()) {
3291 String marker = _parsingContext.inArray() ? "Array" : "Object";
3292 _reportInvalidEOF(String.format(
3293 ": expected close marker for %s (start marker at %s)",
3294 marker,
3295 _parsingContext.getStartLocation(_ioContext.getSourceReference())),
3296 null);
3297 }
3298 }
3299
3300
3305
3306 protected JsonToken _handleCBOREOF() throws IOException {
3307
3311 _tagValue = -1;
3312 close();
3313 return (_currToken = null);
3314 }
3315
3316 protected void _invalidToken(int ch) throws JsonParseException {
3317 ch &= 0xFF;
3318 if (ch == 0xFF) {
3319 throw _constructError("Mismatched BREAK byte (0xFF): encountered where value expected");
3320 }
3321 throw _constructError("Invalid CBOR value token (first byte): 0x"+Integer.toHexString(ch));
3322 }
3323
3324 protected void _reportUnexpectedBreak() throws IOException {
3325 if (_parsingContext.inRoot()) {
3326 throw _constructError("Unexpected Break (0xFF) token in Root context");
3327 }
3328 throw _constructError("Unexpected Break (0xFF) token in definite length ("
3329 +_parsingContext.getExpectedLength()+") "
3330 +(_parsingContext.inObject() ? "Object" : "Array" ));
3331 }
3332
3333 protected void _reportInvalidChar(int c) throws JsonParseException {
3334
3335 if (c < ' ') {
3336 _throwInvalidSpace(c);
3337 }
3338 _reportInvalidInitial(c);
3339 }
3340
3341 protected void _reportInvalidInitial(int mask) throws JsonParseException {
3342 _reportError("Invalid UTF-8 start byte 0x"+Integer.toHexString(mask));
3343 }
3344
3345 protected void _reportInvalidOther(int mask) throws JsonParseException {
3346 _reportError("Invalid UTF-8 middle byte 0x"+Integer.toHexString(mask));
3347 }
3348
3349 protected void _reportInvalidOther(int mask, int ptr) throws JsonParseException {
3350 _inputPtr = ptr;
3351 _reportInvalidOther(mask);
3352 }
3353
3354
3359
3360 private final static BigInteger BIT_63 = BigInteger.ONE.shiftLeft(63);
3361
3362 private final BigInteger _bigPositive(long l) {
3363 BigInteger biggie = BigInteger.valueOf((l << 1) >>> 1);
3364 return biggie.or(BIT_63);
3365 }
3366
3367 private final BigInteger _bigNegative(long l) {
3368
3369 BigInteger unsignedBase = _bigPositive(l);
3370 return unsignedBase.negate().subtract(BigInteger.ONE);
3371 }
3372 }
3373