Skip to content

Commit

Permalink
Add extra writeNumber() method in TokenBuffer (#4699)
Browse files Browse the repository at this point in the history
  • Loading branch information
pjfanning authored Sep 13, 2024
1 parent 7c336bf commit ef871bb
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 4 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ Project: jackson-databind
(contributed by Carter K)
#4694: Deserializing `BigDecimal` with large number of decimals result in incorrect value
(reported by @lnthai2002)
#4699: Add extra `writeNumber()` method in `TokenBuffer`
(contributed by @pjfanning)
2.17.2 (05-Jul-2024)
Expand Down
27 changes: 23 additions & 4 deletions src/main/java/com/fasterxml/jackson/databind/util/TokenBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,27 @@ public void writeNumber(String encodedValue) throws IOException {
_appendValue(JsonToken.VALUE_NUMBER_FLOAT, encodedValue);
}

/**
* Write method that can be used for custom numeric types that can
* not be (easily?) converted to "standard" Java number types.
* Because numbers are not surrounded by double quotes, regular
* {@link #writeString} method can not be used; nor
* {@link #writeRaw} because that does not properly handle
* value separators needed in Array or Object contexts.
*
* @param encodedValue Textual (possibly formatted) number representation to write
* @param isInteger Whether value should be considered an integer
*
* @throws IOException if there is either an underlying I/O problem or encoding
* issue at format layer
* @since 2.18
*/
public void writeNumber(String encodedValue, boolean isInteger) throws IOException {
_appendValue(
isInteger ? JsonToken.VALUE_NUMBER_INT : JsonToken.VALUE_NUMBER_FLOAT,
encodedValue);
}

private void writeLazyInteger(Object encodedValue) throws IOException {
_appendValue(JsonToken.VALUE_NUMBER_INT, encodedValue);
}
Expand Down Expand Up @@ -1853,8 +1874,7 @@ public float getFloatValue() throws IOException {
@Override
public int getIntValue() throws IOException
{
Number n = (_currToken == JsonToken.VALUE_NUMBER_INT) ?
((Number) _currentObject()) : getNumberValue();
final Number n = getNumberValue(false);
if ((n instanceof Integer) || _smallerThanInt(n)) {
return n.intValue();
}
Expand All @@ -1863,8 +1883,7 @@ public int getIntValue() throws IOException

@Override
public long getLongValue() throws IOException {
Number n = (_currToken == JsonToken.VALUE_NUMBER_INT) ?
((Number) _currentObject()) : getNumberValue();
final Number n = getNumberValue(false);
if ((n instanceof Long) || _smallerThanLong(n)) {
return n.longValue();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,57 @@ public void testNumberOverflowLong() throws IOException
}
}

@Test
public void testNumberIntAsString() throws IOException
{
try (TokenBuffer buf = new TokenBuffer(null, false)) {
buf.writeNumber("123", true);
try (JsonParser p = buf.asParser()) {
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(NumberType.BIG_INTEGER, p.getNumberType());
assertEquals(123, p.getIntValue());
}
}
try (TokenBuffer buf = new TokenBuffer(null, false)) {
buf.writeNumber("-123", true);
try (JsonParser p = buf.asParser()) {
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(NumberType.BIG_INTEGER, p.getNumberType());
assertEquals(-123L, p.getLongValue());
}
}
try (TokenBuffer buf = new TokenBuffer(null, false)) {
buf.writeNumber("123", false);
try (JsonParser p = buf.asParser()) {
assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
assertEquals(NumberType.BIG_DECIMAL, p.getNumberType());
assertEquals(123.0, p.getFloatValue());
}
}
// legacy method assumes Decimal type
try (TokenBuffer buf = new TokenBuffer(null, false)) {
buf.writeNumber("123");
try (JsonParser p = buf.asParser()) {
assertToken(JsonToken.VALUE_NUMBER_FLOAT, p.nextToken());
assertEquals(NumberType.BIG_DECIMAL, p.getNumberType());
assertEquals(123.0, p.getFloatValue());
}
}
}

@Test
public void testNumberNonIntAsStringNoCoerce() throws IOException
{
try (TokenBuffer buf = new TokenBuffer(null, false)) {
buf.writeNumber("1234.567", true);
try (JsonParser p = buf.asParser()) {
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(NumberType.BIG_INTEGER, p.getNumberType());
assertThrows(NumberFormatException.class, p::getIntValue);
}
}
}

@Test
public void testBigIntAsString() throws IOException
{
Expand Down

0 comments on commit ef871bb

Please sign in to comment.