dahomey-technologies/Dahomey.Cbor

How to convert CborValue to standard .NET type?

Closed this issue · 2 comments

bjh0 commented

I am experimenting with this library, and I am new to CBOR as well - so please excuse my ignorance in advance.

I have set up an embedded system to exchange some CBOR messages. But, because it is a resource limited platform, rather than use string based keys I am using integers for the keys instead, and then both the embedded side and the PC side need to 'know' which integer key relates to which object properties, so that the messages can be understood at each end.

The Dahomey.Cbor documentation talks about deserialisation from any C# class:

class CustomObject
{
  ...
}

CustomObject customObject = await Cbor.DeserializeAsync<CustomObject>(stream);

I tried that and it doesn't work. But I imagine it's because I am using integers for keys, so obviously the deserialiser doesn't know how to map the CBOR message to the class properties. I assume there's no workaround for this that I'm missing?

Anyway, I moved on and decided I'd deserialise as a CborObject instead, and this is working fine. To get at each value, I can just do this (code simplified for the sake of brevity):

co = await Cbor.DeserializeAsync<CborObject>(stream);
var i = co[2];

Where '2' in this case is the integer key.

Now the problem is, the values I get back are of type CborValue, or some type that inherits from CborValue. In the case of an unsigned integer value, for example, I get a CborPositive type.

But when I'm working with these values, I don't want them as CborValue types, I want to work with them as standard .NET types (integer, double, string, etc). But there appears to be no built in way to do that in the library.

There is a way to get the value back as a string from the library, since it overrides .ToString(). So obviously I could do something convoluted like this:

string nAsString = co[2].ToString();
int n = Convert.ToInt32(nAsString);

But I feel like I am fighting against the library, and possibly there's a much simpler way to achieve what I am trying to do that I am missing.
If so, please enlighten me!

rmja commented

The first case with int keys should work, see #92.

Note that it does not serialize to a map but an array where the int keys are array indices.

Hi,

The CborObjectFormat can support int keys for arrays or maps:

  • can serialize class/struct as a string keyed CBOR map (original & default implementation)
  • can serialize class/struct as an integer keyed CBOR map (integer key value defined in CborPropertyAttribute)
  • can serialize class/struct as a CBOR array (array index defined in CborPropertyAttribute)
  • does not yet support Discriminators nor CreatorMappings

check examples here:
https://github.com/dahomey-technologies/Dahomey.Cbor/blob/master/src/Dahomey.Cbor.Tests/ObjectFormatTests.cs

Michaël