javajsonserializationjacksoncbor

Serialize fixed size Map to CBOR


I have the following JSON:

[
  {
    2: {
      "c": true
    }
  },
  {
    3: {
      "p": 10
    }
  }
]

That I would like to convert to CBOR format. Accordingly to cbor.me I have the following output:

82A102A16163F5A103A161700A

But, when using Jackson Binary CBOR Serializer, I have the following output:

82BF02BF6163F5FFFFBF03BF61700AFFFF

Which is not wrong, but not optimized... I have an extra 4 unnecessary bytes added to what it can really be.

I've then tried to manually serialize the JSON but same result:

@Override
public void serialize(Request value, JsonGenerator jgen, SerializerProvider provider)
        throws IOException, JsonProcessingException {
    jgen.writeStartArray(value.getDataList().size());
    for (Data data : value.getDataList()) {
        jgen.writeStartObject(new Map[1]);
        jgen.writeFieldId(data.getItem());
        jgen.writeStartObject();
        if (data.getObject().getC() != null) {
            jgen.writeBooleanField("c", data.getObject().getC());
        }
        if (data.getObject().getP() != null) {
            jgen.writeNumberField("p", data.getObject().getP());
        }
        jgen.writeEndObject();
        jgen.writeEndObject();
    }
    jgen.writeEndArray();
}

Is this a bug with Jackson Binary format library or am I missing some configuration properties from the ObjectMapper?

EDIT: This seems to be a known issue: https://github.com/FasterXML/jackson-dataformats-binary/issues/3


Solution

  • By using version 2.9.4 the following method is available in the CBORGenerator class: public final void writeStartObject(int elementsToWrite)

    @Override
    public void serialize(Request value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonProcessingException {
        jgen.writeStartArray(value.getDataList().size());
        for (Data data : value.getDataList()) {
            ((CBORGenerator) jgen).writeStartObject(1);
            jgen.writeFieldId(data.getItem());
            ((CBORGenerator) jgen).writeStartObject(1);
            if (data.getObject().getC() != null) {
                jgen.writeBooleanField("c", data.getObject().getC());
            }
            if (data.getObject().getP() != null) {
                jgen.writeNumberField("p", data.getObject().getP());
            }
            jgen.writeEndObject();
            jgen.writeEndObject();
        }
        jgen.writeEndArray();
    }
    

    And I have the following output:

    82A102A16163F5A103A161700A