UnionReader.java
package com.fasterxml.jackson.dataformat.avro.deser;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonToken;
/**
* Reader used in cases where union contains at least one non-scalar type.
*/
final class UnionReader extends AvroStructureReader
{
private final AvroStructureReader[] _memberReaders;
private final AvroParserImpl _parser;
public UnionReader(AvroStructureReader[] memberReaders) throws IOException {
this(null, memberReaders, null);
}
private UnionReader(AvroReadContext parent,
AvroStructureReader[] memberReaders, AvroParserImpl parser) throws IOException
{
super(parent, TYPE_ROOT, null);
_memberReaders = memberReaders;
_parser = parser;
if (parser != null)
parser.streamReadConstraints().validateNestingDepth(_nestingDepth);
}
@Override
public UnionReader newReader(AvroReadContext parent, AvroParserImpl parser) throws IOException {
return new UnionReader(parent, _memberReaders, parser);
}
@Override
public JsonToken nextToken() throws IOException
{
int index = _parser.decodeIndex();
// important: remember to create new instance
// also: must pass our parent (not this instance)
AvroStructureReader reader = _memberReaders[index].newReader(_parent, _parser);
return (_currToken = reader.nextToken());
}
@Override
public void skipValue(AvroParserImpl parser) throws IOException {
int index = _decodeIndex(parser.decodeIndex());
// NOTE: no need to create new instance since it's stateless call and
// we pass decoder to use
_memberReaders[index].skipValue(parser);
}
@Override
public String nextFieldName() throws IOException {
nextToken();
return null;
}
@Override
protected void appendDesc(StringBuilder sb) {
sb.append('?');
}
private final int _decodeIndex(int index) throws IOException {
if (index < 0 || index >= _memberReaders.length) {
throw new JsonParseException(_parser, String.format
("Invalid index (%s); union only has %d types", index, _memberReaders.length));
}
return index;
}
}