Skip to content

Commit

Permalink
Fix #373: remove CBORParser.nextTextValue() implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Apr 7, 2023
1 parent 7459723 commit 9c67570
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 222 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1548,232 +1548,16 @@ public String nextFieldName() throws IOException
return (nextToken() == JsonToken.FIELD_NAME) ? getCurrentName() : null;
}

// 06-Apr-2023, tatu: Before Jackson 2.15, we had optimized variant, but
// due to sheer complexity this was removed from 2.15 to avoid subtle
// bugs (like [dataformats-binary#372]
@Override
public String nextTextValue() throws IOException
{
_numTypesValid = NR_UNKNOWN;
if (_tokenIncomplete) {
_skipIncomplete();
}
_tokenInputTotal = _currInputProcessed + _inputPtr;
_binaryValue = null;
_tagValues.clear();

if (_streamReadContext.inObject()) {
if (_currToken != JsonToken.FIELD_NAME) {
// completed the whole Object?
if (!_streamReadContext.expectMoreValues()) {
_stringRefs.pop();
_streamReadContext = _streamReadContext.getParent();
_currToken = JsonToken.END_OBJECT;
return null;
}
_currToken = _decodePropertyName();
return null;
}
} else {
if (!_streamReadContext.expectMoreValues()) {
_stringRefs.pop();
_streamReadContext = _streamReadContext.getParent();
_currToken = JsonToken.END_ARRAY;
return null;
}
}
if (_inputPtr >= _inputEnd) {
if (!loadMore()) {
_eofAsNextToken();
return null;
}
}
int ch = _inputBuffer[_inputPtr++] & 0xFF;
int type = (ch >> 5);
int lowBits = ch & 0x1F;

// One special case: need to consider tag as prefix first:
while (type == 6) {
_tagValues.add(_decodeTag(lowBits));
if (_inputPtr >= _inputEnd) {
if (!loadMore()) {
_eofAsNextToken();
return null;
}
}
ch = _inputBuffer[_inputPtr++] & 0xFF;
type = (ch >> 5);
lowBits = ch & 0x1F;
}

switch (type) {
case 0: // positive int
_numTypesValid = NR_INT;
if (lowBits <= 23) {
_numberInt = lowBits;
} else {
switch (lowBits - 24) {
case 0:
_numberInt = _decode8Bits();
break;
case 1:
_numberInt = _decode16Bits();
break;
case 2:
// 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
{
int v = _decode32Bits();
if (v < 0) {
long l = (long) v;
_numberLong = l & 0xFFFFFFFFL;
_numTypesValid = NR_LONG;
} else{
_numberInt = v;
}
}
break;
case 3:
// 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
{
long l = _decode64Bits();
if (l >= 0L) {
_numberLong = l;
_numTypesValid = NR_LONG;
} else {
_numberBigInt = _bigPositive(l);
_numTypesValid = NR_BIGINT;
}
}
break;
default:
_invalidToken(ch);
}
}
if (_handleTaggedInt(_tagValues) == JsonToken.VALUE_STRING) {
return getText();
}
return null;
case 1: // negative int
_numTypesValid = NR_INT;
if (lowBits <= 23) {
_numberInt = -lowBits - 1;
} else {
switch (lowBits - 24) {
case 0:
_numberInt = -_decode8Bits() - 1;
break;
case 1:
_numberInt = -_decode16Bits() - 1;
break;
case 2:
// 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
{
int v = _decode32Bits();
if (v < 0) {
long unsignedBase = (long) v & 0xFFFFFFFFL;
_numberLong = -unsignedBase - 1L;
_numTypesValid = NR_LONG;
} else {
_numberInt = -v - 1;
}
}
break;
case 3:
// 15-Oct-2016, as per [dataformats-binary#30], we got an edge case here
{
long l = _decode64Bits();
if (l >= 0L) {
_numberLong = l;
_numTypesValid = NR_LONG;
} else {
_numberBigInt = _bigNegative(l);
_numTypesValid = NR_BIGINT;
}
}
break;
default:
_invalidToken(ch);
}
}
_currToken = JsonToken.VALUE_NUMBER_INT;
return null;

case 2: // byte[]
_typeByte = ch;
_tokenIncomplete = true;
_currToken = JsonToken.VALUE_EMBEDDED_OBJECT;
return null;

case 3: // String
_typeByte = ch;
_tokenIncomplete = true;
_currToken = JsonToken.VALUE_STRING;
return _finishTextToken(ch);

case 4: // Array
_currToken = JsonToken.START_ARRAY;
{
int len = _decodeExplicitLength(lowBits);
createChildArrayContext(len);
}
return null;

case 5: // Object
_currToken = JsonToken.START_OBJECT;
{
int len = _decodeExplicitLength(lowBits);
createChildObjectContext(len);
}
return null;

case 7:
default: // misc: tokens, floats
switch (lowBits) {
case 20:
_currToken = JsonToken.VALUE_FALSE;
return null;
case 21:
_currToken = JsonToken.VALUE_TRUE;
return null;
case 22:
_currToken = JsonToken.VALUE_NULL;
return null;
case 23:
_currToken = _decodeUndefinedValue();
return null;

case 25: // 16-bit float...
// As per [http://stackoverflow.com/questions/5678432/decompressing-half-precision-floats-in-javascript]
{
_numberFloat = _decodeHalfSizeFloat();
_numTypesValid = NR_FLOAT;
}
_currToken = JsonToken.VALUE_NUMBER_FLOAT;
return null;
case 26: // Float32
{
_numberFloat = Float.intBitsToFloat(_decode32Bits());
_numTypesValid = NR_FLOAT;
}
_currToken = JsonToken.VALUE_NUMBER_FLOAT;
return null;
case 27: // Float64
_numberDouble = Double.longBitsToDouble(_decode64Bits());
_numTypesValid = NR_DOUBLE;
_currToken = JsonToken.VALUE_NUMBER_FLOAT;
return null;
case 31: // Break
if (_streamReadContext.inArray()) {
if (!_streamReadContext.hasExpectedLength()) {
_stringRefs.pop();
_streamReadContext = _streamReadContext.getParent();
_currToken = JsonToken.END_ARRAY;
return null;
}
}
// Object end-marker can't occur here
_reportUnexpectedBreak();
}
_currToken = _decodeSimpleValue(lowBits, ch);
return null;
if (nextToken() == JsonToken.VALUE_STRING) {
return getText();
}
return null;
}

@Override
Expand Down
2 changes: 2 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Active maintainers:
=== Releases ===
------------------------------------------------------------------------

#373: (cbor) Remove optimized `CBORParser.nextTextValue()` implementation

2.15.0-rc2 (28-Mar-2023)

#347: (cbor) Add support for CBOR stringref extension (`CBORGenerator.Feature.STRINGREF`)
Expand Down

0 comments on commit 9c67570

Please sign in to comment.