AsyncLocation1412Test.java
package com.fasterxml.jackson.core.json.async;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.core.async.AsyncTestBase;
import com.fasterxml.jackson.core.async.ByteArrayFeeder;
import static org.junit.jupiter.api.Assertions.assertEquals;
class AsyncLocation1412Test extends AsyncTestBase
{
private static final JsonFactory jsonFactory = new JsonFactory();
private static final byte[] json = "[true]".getBytes(StandardCharsets.UTF_8);
static class TokenAndByteOffsets {
public final JsonToken token;
public final long tokenByteOffset;
public final long parserByteOffset;
public TokenAndByteOffsets(JsonToken token,
long tokenByteOffset,
long parserByteOffset) {
this.token = token;
this.tokenByteOffset = tokenByteOffset;
this.parserByteOffset = parserByteOffset;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof TokenAndByteOffsets)) {
return false;
}
TokenAndByteOffsets other = (TokenAndByteOffsets) o;
return Objects.equals(token, other.token)
&& tokenByteOffset == other.tokenByteOffset
&& parserByteOffset == other.parserByteOffset;
}
}
/**
* Returns the result of feeding the whole JSON document at once from array offset zero.
*/
private static List<TokenAndByteOffsets> expected() throws Exception {
try (JsonParser parser = jsonFactory.createNonBlockingByteArrayParser()) {
ByteArrayFeeder feeder = (ByteArrayFeeder) parser.getNonBlockingInputFeeder();
feeder.feedInput(json, 0, json.length);
feeder.endOfInput();
return readAvailableTokens(parser);
}
}
// This one passes:
@Test
@DisplayName("Feed one byte at a time from array offset zero")
void feedByteByByteFromOffsetZero() throws Exception {
try (JsonParser parser = jsonFactory.createNonBlockingByteArrayParser()) {
ByteArrayFeeder feeder = (ByteArrayFeeder) parser.getNonBlockingInputFeeder();
List<TokenAndByteOffsets> actual = new ArrayList<>();
for (int i = 0; i < json.length; i++) {
byte[] temp = new byte[]{json[i]};
feeder.feedInput(temp, 0, temp.length);
if (i == json.length - 1) feeder.endOfInput();
actual.addAll(readAvailableTokens(parser));
}
assertEquals(expected(), actual);
}
}
@Test
@DisplayName("Feed one byte at a time from non-zero array offset")
void feedByteByByteFromNonZeroOffset() throws Exception {
try (JsonParser parser = jsonFactory.createNonBlockingByteArrayParser()) {
ByteArrayFeeder feeder = (ByteArrayFeeder) parser.getNonBlockingInputFeeder();
List<TokenAndByteOffsets> actual = new ArrayList<>();
for (int i = 0; i < json.length; i++) {
feeder.feedInput(json, i, i + 1);
if (i == json.length - 1) feeder.endOfInput();
actual.addAll(readAvailableTokens(parser));
}
assertEquals(expected(), actual);
}
}
@Test
@DisplayName("Feed whole document at once from non-zero array offset")
void feedWholeDocumentFromNonZeroOffset() throws Exception {
// Same document, but preceded by a 0 byte.
byte[] jsonOffsetByOne = new byte[json.length + 1];
System.arraycopy(json, 0, jsonOffsetByOne, 1, json.length);
try (JsonParser parser = jsonFactory.createNonBlockingByteArrayParser()) {
ByteArrayFeeder feeder = (ByteArrayFeeder) parser.getNonBlockingInputFeeder();
feeder.feedInput(jsonOffsetByOne, 1, jsonOffsetByOne.length);
feeder.endOfInput();
assertEquals(expected(), readAvailableTokens(parser));
}
}
private static List<TokenAndByteOffsets> readAvailableTokens(JsonParser parser) throws Exception
{
List<TokenAndByteOffsets> result = new ArrayList<>();
while (true) {
JsonToken token = parser.nextToken();
if (token == JsonToken.NOT_AVAILABLE || token == null) return result;
result.add(new TokenAndByteOffsets(
token,
parser.currentTokenLocation().getByteOffset(),
parser.currentLocation().getByteOffset())
);
}
}
}