jackson-core icon indicating copy to clipboard operation
jackson-core copied to clipboard

JsonParser.getCurrentLocation is not updated for `DataInput` input

Open fabienrenaud opened this issue 4 years ago • 3 comments

Issue

Using a JsonParser instantiated via JsonParser.createParser(DataInput) does not update JsonLocation values returned by JsonParser.getCurrentLocation (everything defaults to -1).

Switching to JsonParser.createParser(InputStream) with the same input object populates the JsonLocation data as expected.

Use case

I use JsonParser to manually extract slices of Netty byte buffers (that contain Json). To feed Netty ByteBufs to JsonParser, I have to wrap the ByteBuf in a ByteBufInputStream which extends InputStream and implements DataInput. JsonParser accepts both types so explicit casting is required.

  • This works and populates JsonLocation values:
ByteBuf buf = ...;
JsonParser parser = JSON_FACTORY.createParser((InputStream) new ByteBufInputStream(buf));
  • This does not populate JsonLocation values:
ByteBuf buf = ...;
JsonParser parser = JSON_FACTORY.createParser((DataInput) new ByteBufInputStream(buf));

Issue affects at least versions 2.9.8 and 2.10.2.

fabienrenaud avatar Feb 20 '20 22:02 fabienrenaud

Yeah, this is missing, as there is no input pointer to use. So it's not a simple tweak.

cowtowncoder avatar Feb 20 '20 23:02 cowtowncoder

I am not sure why it works for InputStream and not DataInput though. Are there any methods InputStream provides that DataInput does not (to make this work in Jackson)?

fabienrenaud avatar Feb 20 '20 23:02 fabienrenaud

It's just because all reads from InputStream / Reader are buffered first and access is from those buffers; single-byte/char reads are not used. In contrast, DataInput is read byte-by-byte (leading to lower performance). There is no way to safely try bulk reads either, as far as I know. So to keep track of location, separate byte counter would need to be maintained.

cowtowncoder avatar Feb 21 '20 00:02 cowtowncoder