Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CBOR - There is no way to deserialize a map with ByteString values #2037

Closed
tobias-wahlstrom-hqv opened this issue Sep 19, 2022 · 3 comments
Closed

Comments

@tobias-wahlstrom-hqv
Copy link

I am interfacing an existing system that contains a map from numbers to byte strings (major type 2). My first attemt to handle this was to just decode to the type:

Map<Int, ByteArray>

Since the default encoding/decoding will assume ByteArray are "array of data items" (major type 4). Trying to decode a byte string will result in a runtime error like:

Exception in thread "main" kotlinx.serialization.cbor.internal.CborDecodingException: Expected start of array, but found 41

I can not see that there is a way to make a custom encoding/decoding of maps either. And the @ByteString annotation is only applicable to attributes which not will help in this case.

One possible solution for my case would be to be able to configure what the default encoding/decoding of an ByteArray should be in e.g. the CborBuilder just like ignoreUnknownKeys.

PS.
Also, would like to push for the issue #1529 which makes a lot of sense since you with cbor typically interface with embedded systems where signed bytes normally is the odd case.
DS.

To Reproduce

Run this:

import kotlinx.serialization.cbor.Cbor
import kotlinx.serialization.decodeFromByteArray

fun main() {
    val exampleCborData = byteArrayOf((0xBF).toByte(), 0x1A, 0x12, 0x38, 0x00, 0x00, 0x41, 0x03, (0xFF).toByte())
    Cbor.decodeFromByteArray<Map<Int, ByteArray>>(exampleCborData)
}

Expected behavior

To not throw an exception and return something that looks like this:

BF # map()
1A 12380000 # unsigned(305659904)
41 # bytes(1)
03 # "\u0003"
FF # primitive(
)

{305659904: h'03'}

Environment

  • Kotlin version: 1.7.10
  • Library version: 1.4.0
  • Kotlin platforms: Multiplatform/JVM
  • Gradle version: 7.4.2
@sandwwraith
Copy link
Member

sandwwraith commented Sep 21, 2022

I think promising approach to solve this issue is to allow to use ByteString on types, too, so one could write Map<Int, @ByteString ByteArray>

UPD: But it seems that currently, serial info annotations on type usages are not stored anywhere. Perhaps we should reconsider that.

@JesusMcCloud
Copy link
Contributor

Does #2412 help?

@sandwwraith
Copy link
Member

I think it is possible now if alwaysUseByteString option is enabled. If it is not enough for you for some reason, please re-open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants