diff --git a/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingByteArrayParser.java b/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingByteArrayParser.java index ceb55b9b7..aea407b55 100644 --- a/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingByteArrayParser.java +++ b/smile/src/main/java/tools/jackson/dataformat/smile/async/NonBlockingByteArrayParser.java @@ -6,6 +6,7 @@ import java.io.OutputStream; import java.math.BigDecimal; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import tools.jackson.core.JacksonException; @@ -1583,28 +1584,9 @@ private final JsonToken _finish7BitBinaryBody() throws JacksonException private final String _decodeASCIIText(byte[] inBuf, int inPtr, int len) throws JacksonException { // note: caller ensures we have enough bytes available - char[] outBuf = _textBuffer.emptyAndGetCurrentSegment(); - int outPtr = 0; - - // loop unrolling seems to help here: - for (int inEnd = inPtr + len - 3; inPtr < inEnd; ) { - outBuf[outPtr++] = (char) inBuf[inPtr++]; - outBuf[outPtr++] = (char) inBuf[inPtr++]; - outBuf[outPtr++] = (char) inBuf[inPtr++]; - outBuf[outPtr++] = (char) inBuf[inPtr++]; - } - int left = (len & 3); - if (left > 0) { - outBuf[outPtr++] = (char) inBuf[inPtr++]; - if (left > 1) { - outBuf[outPtr++] = (char) inBuf[inPtr++]; - if (left > 2) { - outBuf[outPtr++] = (char) inBuf[inPtr++]; - } - } - } - _textBuffer.setCurrentLength(len); - return _textBuffer.contentsAsString(); + String str = new String(inBuf, inPtr, len, StandardCharsets.US_ASCII); + _textBuffer.resetWithString(str); + return str; } /** diff --git a/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleStringArrayTest.java b/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleStringArrayTest.java index 4fcfb54bd..3580e5320 100644 --- a/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleStringArrayTest.java +++ b/smile/src/test/java/tools/jackson/dataformat/smile/async/SimpleStringArrayTest.java @@ -57,6 +57,35 @@ public void testShortAsciiStrings() throws IOException _testStrings(input, data, 1, 1); } + @Test + public void testShortAsciiStringAccessorsWithContiguousInput() throws IOException + { + final int[] lengths = { 1, 2, 3, 4, 31, 32, 33, 63, 64 }; + final String[] input = new String[lengths.length]; + for (int i = 0; i < lengths.length; ++i) { + input[i] = _ascii(lengths[i]); + } + byte[] data = _stringDoc(_smileWriter(true), input); + + AsyncReaderWrapper r = asyncForBytes(_smileReader(true), data.length + 1, data, 0); + assertNull(r.currentToken()); + assertToken(JsonToken.START_ARRAY, r.nextToken()); + for (String value : input) { + assertToken(JsonToken.VALUE_STRING, r.nextToken()); + + assertEquals(value, r.currentText()); + assertEquals(value.length(), r.parser().getStringLength()); + + final char[] ch = r.parser().getStringCharacters(); + final int offset = r.parser().getStringOffset(); + final int len = r.parser().getStringLength(); + assertEquals(value, new String(ch, offset, len)); + } + assertToken(JsonToken.END_ARRAY, r.nextToken()); + assertNull(r.nextToken()); + assertTrue(r.isClosed()); + } + @Test public void testShortUnicodeStrings() throws IOException { @@ -203,4 +232,13 @@ private byte[] _stringDoc(ObjectWriter w, String[] input) throws IOException g.close(); return bytes.toByteArray(); } + + private String _ascii(int len) + { + StringBuilder sb = new StringBuilder(len); + for (int i = 0; i < len; ++i) { + sb.append((char) ('a' + (i % 26))); + } + return sb.toString(); + } }