1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
/*
* Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
package kotlinx.serialization.cbor
import kotlinx.serialization.*
import kotlinx.serialization.builtins.*
import kotlinx.serialization.cbor.internal.ByteArrayInput
import kotlinx.serialization.cbor.internal.ByteArrayOutput
import kotlinx.serialization.cbor.internal.*
import kotlinx.serialization.modules.*
/**
* Implements [encoding][encodeToByteArray] and [decoding][decodeFromByteArray] classes to/from bytes
* using [CBOR](https://tools.ietf.org/html/rfc7049) specification.
* It is typically used by constructing an application-specific instance, with configured behaviour, and,
* if necessary, registered custom serializers (in [SerializersModule] provided by [serializersModule] constructor parameter).
*
* ### Known caveats and limitations:
* Supports reading collections of both definite and indefinite lengths; however,
* serialization always writes maps and lists as [indefinite-length](https://tools.ietf.org/html/rfc7049#section-2.2.1) ones.
* Does not support [optional tags](https://tools.ietf.org/html/rfc7049#section-2.4) representing datetime, bignums, etc.
* Fully support CBOR maps, which, unlike JSON ones, may contain keys of non-primitive types, and may produce such maps
* from corresponding Kotlin objects. However, other 3rd-party parsers (e.g. `jackson-dataformat-cbor`) may not accept such maps.
*
* @param encodeDefaults specifies whether default values of Kotlin properties are encoded.
* False by default; meaning that properties with values equal to defaults will be elided.
* @param ignoreUnknownKeys specifies if unknown CBOR elements should be ignored (skipped) when decoding.
*/
@ExperimentalSerializationApi
public sealed class Cbor(
internal val encodeDefaults: Boolean,
internal val ignoreUnknownKeys: Boolean,
override val serializersModule: SerializersModule
) : BinaryFormat {
/**
* The default instance of [Cbor]
*/
public companion object Default : Cbor(false, false, EmptySerializersModule())
override fun <T> encodeToByteArray(serializer: SerializationStrategy<T>, value: T): ByteArray {
val output = ByteArrayOutput()
val dumper = CborWriter(this, CborEncoder(output))
dumper.encodeSerializableValue(serializer, value)
return output.toByteArray()
}
override fun <T> decodeFromByteArray(deserializer: DeserializationStrategy<T>, bytes: ByteArray): T {
val stream = ByteArrayInput(bytes)
val reader = CborReader(this, CborDecoder(stream))
return reader.decodeSerializableValue(deserializer)
}
}
@OptIn(ExperimentalSerializationApi::class)
private class CborImpl(encodeDefaults: Boolean, ignoreUnknownKeys: Boolean, serializersModule: SerializersModule) :
Cbor(encodeDefaults, ignoreUnknownKeys, serializersModule)
/**
* Creates an instance of [Cbor] configured from the optionally given [Cbor instance][from]
* and adjusted with [builderAction].
*/
@ExperimentalSerializationApi
public fun Cbor(from: Cbor = Cbor, builderAction: CborBuilder.() -> Unit): Cbor {
val builder = CborBuilder(from)
builder.builderAction()
return CborImpl(builder.encodeDefaults, builder.ignoreUnknownKeys, builder.serializersModule)
}
/**
* Builder of the [Cbor] instance provided by `Cbor` factory function.
*/
@ExperimentalSerializationApi
public class CborBuilder internal constructor(cbor: Cbor) {
/**
* Specifies whether default values of Kotlin properties should be encoded.
*/
public var encodeDefaults: Boolean = cbor.encodeDefaults
/**
* Specifies whether encounters of unknown properties in the input CBOR
* should be ignored instead of throwing [SerializationException].
* `false` by default.
*/
public var ignoreUnknownKeys: Boolean = cbor.ignoreUnknownKeys
/**
* Module with contextual and polymorphic serializers to be used in the resulting [Cbor] instance.
*/
public var serializersModule: SerializersModule = cbor.serializersModule
}
|