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

CBOR - Default generator generates object with map(*) instead of map(2) #376

Open x-devel opened 1 year ago

x-devel commented 1 year ago

Hey there! I'm using the CBOR jackson library with Kotlin and I'm having some issues when performing a CBOR encoding of an object. In this example I'm serializing the Person class to a CBOR byte array and then visualizing it in its hex form with an extension function on the ByteArray class.

val person = Person("John", "Doe")
val mapper = CBORMapper().registerKotlinModule()
val cborHex = mapper.writeValueAsBytes(person).toHex()
println(cborHex)

Consider that the Person class is mapped in this particular way

data class Person(
    @JsonProperty("0")
    val name: String,
    @JsonProperty("1")
    val surname: String
)

The output that I'm getting with the code that I've just shown is: bf6130644a6f686e613163446f65ff - 15 bytes but looking at the CBOR playground website I should instead be getting the optimal output which is: A26130644A6F686E613163446F65 - 14 bytes. I think that the issue is caused by the default parser that considers maps and arrays as collections of indefinite size when parsing them instead of starting object and arrays indicating their respective sizes.

So, is there a solution on what to do to get the optimal output?

cowtowncoder commented 1 year ago

(I assume you mean "generator" instead of "parser" in above).

Yes, the current CBORGenerator encodes Objects and Maps using indefinite length marker (and end marker). This is legal output and is a trade-off (encoding is easier when there is no requirement to ensure specific length before output). There is currently no way to make output use length-prefix for Objects (there is for Arrays); issue #3 is for adding such support: it would be easier to add for Java Maps than POJOs (mostly due to possible JSON Filters for POJOs).