-
-
Notifications
You must be signed in to change notification settings - Fork 815
Open
Description
I'm currently trying to use jackson-dataformat-cbor:2.19.0
and want to parse custom tags. Since I couldn't find specific examples, I attempted to implement it with the following code.
public class CborParserDelegate extends JsonParserDelegate {
protected final CBORParser delegate;
public CborParserDelegate(CBORParser d) {
super(d);
this.delegate = d;
}
@Override
public CBORParser delegate() {
return (CBORParser) super.delegate();
}
public int getCurrentTag() {
return delegate().getCurrentTag();
}
public CBORParser.TagList getCurrentTags() {
return delegate().getCurrentTags();
}
}
public class CustomTagsCborParser extends CborParserDelegate {
public CustomTagsCborParser(CBORParser d) {
super(d);
try {
this.method = ParserMinimalBase.class.getDeclaredMethod("_updateToken", JsonToken.class);
this.method.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private final Method method;
private Object customValue;
@Override
public JsonToken nextToken() throws IOException {
JsonToken jsonToken = super.nextToken();
int currentTag = delegate.getCurrentTag();
if (currentTag != -1) {
ObjectCodec codec = getCodec();
this.customValue = mapValue(currentTag, codec.readTree(delegate));
return Err.call(() -> (JsonToken) method.invoke(delegate, JsonToken.VALUE_EMBEDDED_OBJECT));
}
return jsonToken;
}
@Override
public Object getEmbeddedObject() throws IOException {
if (this.customValue != null) {
Object v = this.customValue;
this.customValue = null;
return v;
}
return super.getEmbeddedObject();
}
private Object mapValue(int tag, TreeNode treeNode) {
CustomTag customTag = CustomTag.of(tag);
switch (customTag) {
case TAG_12: {
_assert(treeNode.isArray(), "TAG_12 should be an array with two items.");
ArrayNode arrayNode = (ArrayNode) treeNode;
long seconds = arrayNode.get(0).asLong(0);
long nanoSeconds = arrayNode.get(1).asLong(0);
return Instant.ofEpochSecond(seconds, nanoSeconds);
}
case TAG_14: {
_assert(treeNode.isArray(), "TAG_14 should be an array with two items.");
ArrayNode arrayNode = (ArrayNode) treeNode;
long seconds = arrayNode.at("/0").asLong(0);
long nanoSeconds = arrayNode.at("/1").asLong(0);
return Duration.ofSeconds(seconds, nanoSeconds);
}
default:
return treeNode;
}
}
private void _assert(boolean state, String message) {
if (!state) {
throw new IllegalStateException(message);
}
}
}
However, since CborParser
inherits from ParserMinimalBase
, calling its _updateToken(JsonToken)
method requires reflection, which I'd like to avoid.
So my questions are:
- Is my approach for custom tag parsing with dataformat-cbor correct (or aligned with your design)? If not, what should I do instead?
- Is there a way to avoid using reflection when updating tokens?
Metadata
Metadata
Assignees
Labels
No labels