FasterXML / jackson-dataformats-binary

Uber-project for standard Jackson binary format backends: avro, cbor, ion, protobuf, smile
Apache License 2.0
310 stars 133 forks source link

Structured keys (Array, Object) not supported #280

Open axelczk opened 3 years ago

axelczk commented 3 years ago

I was doing some test on my projet using your library, and an exception was thrown for a major type 4 not supported on this payload:

Diagnostic payload: {[3,0,0]:"test"}

But the major type 4 is working with this one: [{0: "0"}, {0: "1"}]

I'm using the default CBORMapper, with the method: readValues(buffer, Object.class) for this test.

Is this a problem on the library ? Or it's not supported ? In the second case, do you plan to support it in the future ?

cowtowncoder commented 3 years ago

@axelczk Please include some kind of reproduction, and perhaps stack trace / exception message. Is the issue with values or key type? And why are you using readValues() (or should that be readValue())?

axelczk commented 3 years ago

Here is a payload that fails:

0xA1, 0x83 , 0x03, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74 

The problem is: the library doesn't accept array as a fieldName.

The exception is thrown in: _decodeNonStringName(int) :

throw _constructError("Unsupported major type ("+type+") for CBOR Objects, not (yet?) supported, only Strings");
cowtowncoder commented 3 years ago

Correct: this is not supported and I am not quite sure how it could be -- it would require transformation of some kind from whatever array type is being used into Java String, essentially. If this was, say, a byte[] equivalent containing UTF-8 encoded name, that'd be easy enough, but without some kind of metadata or configuration it is not safe to assume this in general.

axelczk commented 3 years ago

I would say you should deserialize it in the same way as when a value is an array but it's easier said than done.

Thanks you for your answer. It's very appreciated !

cowtowncoder commented 3 years ago

The problem is not deserialization as these values can be decoded as values. The problem is that of exposing it via token stream; Object keys are exposed as JsonToken.FIELD_NAME for which String accessor (only) exists. Plus some support for int/long keys. While it'd be possible to expose other types for CBOR backend, the question beyond that is how to make use of that via databind.

So it is all possible, just quite a bit of work and needing to fit with the API approach.