Skip to content

Commit 9b3f0e5

Browse files
committed
fix tagging
1 parent 775b929 commit 9b3f0e5

File tree

7 files changed

+246
-99
lines changed

7 files changed

+246
-99
lines changed

formats/cbor/commonMain/src/kotlinx/serialization/cbor/CborElement.kt

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ public sealed class CborPrimitive<T : Any>(
8888
")"
8989
}
9090
}
91+
9192
@Serializable(with = CborIntSerializer::class)
9293
public sealed class CborInt<T : Any>(
9394
tags: ULongArray = ulongArrayOf(),
@@ -96,13 +97,14 @@ public sealed class CborInt<T : Any>(
9697
public companion object {
9798
public operator fun invoke(
9899
value: Long,
99-
tags: ULongArray = ulongArrayOf()
100-
): CborInt<*> = if (value >= 0) CborPositiveInt(value.toULong(), tags) else CborNegativeInt(value, tags)
100+
vararg tags: ULong
101+
): CborInt<*> =
102+
if (value >= 0) CborPositiveInt(value.toULong(), tags = tags) else CborNegativeInt(value, tags = tags)
101103

102104
public operator fun invoke(
103105
value: ULong,
104-
tags: ULongArray = ulongArrayOf()
105-
): CborInt<ULong> = CborPositiveInt(value, tags)
106+
vararg tags: ULong
107+
): CborInt<ULong> = CborPositiveInt(value, tags = tags)
106108
}
107109
}
108110

@@ -112,7 +114,7 @@ public sealed class CborInt<T : Any>(
112114
@Serializable(with = CborNegativeIntSerializer::class)
113115
public class CborNegativeInt(
114116
value: Long,
115-
tags: ULongArray = ulongArrayOf()
117+
vararg tags: ULong
116118
) : CborInt<Long>(tags, value) {
117119
init {
118120
require(value < 0) { "Number must be negative: $value" }
@@ -125,7 +127,7 @@ public class CborNegativeInt(
125127
@Serializable(with = CborPositiveIntSerializer::class)
126128
public class CborPositiveInt(
127129
value: ULong,
128-
tags: ULongArray = ulongArrayOf()
130+
vararg tags: ULong
129131
) : CborInt<ULong>(tags, value)
130132

131133
/**
@@ -134,7 +136,7 @@ public class CborPositiveInt(
134136
@Serializable(with = CborDoubleSerializer::class)
135137
public class CborDouble(
136138
value: Double,
137-
tags: ULongArray = ulongArrayOf()
139+
vararg tags: ULong
138140
) : CborPrimitive<Double>(value, tags)
139141

140142
/**
@@ -143,7 +145,7 @@ public class CborDouble(
143145
@Serializable(with = CborStringSerializer::class)
144146
public class CborString(
145147
value: String,
146-
tags: ULongArray = ulongArrayOf()
148+
vararg tags: ULong
147149
) : CborPrimitive<String>(value, tags)
148150

149151
/**
@@ -161,7 +163,7 @@ public class CborBoolean(
161163
@Serializable(with = CborByteStringSerializer::class)
162164
public class CborByteString(
163165
value: ByteArray,
164-
tags: ULongArray = ulongArrayOf()
166+
vararg tags: ULong
165167
) : CborPrimitive<ByteArray>(value, tags) {
166168
override fun equals(other: Any?): Boolean {
167169
if (this === other) return true
@@ -189,7 +191,7 @@ public class CborByteString(
189191
* Class representing CBOR `null` value
190192
*/
191193
@Serializable(with = CborNullSerializer::class)
192-
public class CborNull(tags: ULongArray = ulongArrayOf()) : CborPrimitive<Unit>(Unit, tags)
194+
public class CborNull(vararg tags: ULong) : CborPrimitive<Unit>(Unit, tags)
193195

194196
/**
195197
* Class representing CBOR map, consisting of key-value pairs, where both key and value are arbitrary [CborElement]
@@ -200,7 +202,7 @@ public class CborNull(tags: ULongArray = ulongArrayOf()) : CborPrimitive<Unit>(U
200202
@Serializable(with = CborMapSerializer::class)
201203
public class CborMap(
202204
private val content: Map<CborElement, CborElement>,
203-
tags: ULongArray = ulongArrayOf()
205+
vararg tags: ULong
204206
) : CborElement(tags), Map<CborElement, CborElement> by content {
205207

206208
public override fun equals(other: Any?): Boolean =
@@ -226,7 +228,7 @@ public class CborMap(
226228
@Serializable(with = CborListSerializer::class)
227229
public class CborList(
228230
private val content: List<CborElement>,
229-
tags: ULongArray = ulongArrayOf()
231+
vararg tags: ULong
230232
) : CborElement(tags), List<CborElement> by content {
231233

232234
public override fun equals(other: Any?): Boolean =

formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/CborElementSerializers.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,7 @@ private fun defer(deferred: () -> SerialDescriptor): SerialDescriptor = object :
323323

324324
private fun CborWriter.encodeTags(value: CborElement) { // Encode tags if present
325325
if (value.tags.isNotEmpty()) {
326-
for (tag in value.tags) {
327-
encodeTag(tag)
328-
}
326+
encodeTags(value.tags)
329327
}
330328

331329
}

formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/CborTreeReader.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,20 @@ internal class CborTreeReader(
2828
val result = when (parser.curByte shr 5) { // Get major type from the first 3 bits
2929
0 -> { // Major type 0: unsigned integer
3030
val value = parser.nextNumber()
31-
CborPositiveInt(value.toULong(), tags)
31+
CborPositiveInt(value.toULong(), tags = tags)
3232
}
3333

3434
1 -> { // Major type 1: negative integer
3535
val value = parser.nextNumber()
36-
CborNegativeInt(value, tags)
36+
CborNegativeInt(value, tags = tags)
3737
}
3838

3939
2 -> { // Major type 2: byte string
40-
CborByteString(parser.nextByteString(), tags)
40+
CborByteString(parser.nextByteString(), tags = tags)
4141
}
4242

4343
3 -> { // Major type 3: text string
44-
CborString(parser.nextString(), tags)
44+
CborString(parser.nextString(), tags = tags)
4545
}
4646

4747
4 -> { // Major type 4: array
@@ -66,10 +66,10 @@ internal class CborTreeReader(
6666

6767
0xF6, 0xF7 -> {
6868
parser.nextNull()
69-
CborNull(tags)
69+
CborNull(tags = tags)
7070
}
7171
// Half/Float32/Float64
72-
NEXT_HALF, NEXT_FLOAT, NEXT_DOUBLE -> CborDouble(parser.nextDouble(), tags)
72+
NEXT_HALF, NEXT_FLOAT, NEXT_DOUBLE -> CborDouble(parser.nextDouble(), tags = tags)
7373
else -> throw CborDecodingException(
7474
"Invalid simple value or float type: ${parser.curByte.toString(16).uppercase()}"
7575
)
@@ -120,7 +120,7 @@ internal class CborTreeReader(
120120
parser.end()
121121
}
122122

123-
return CborList(elements, tags)
123+
return CborList(elements, tags = tags)
124124
}
125125

126126
private fun readMap(tags: ULongArray): CborMap {
@@ -144,6 +144,6 @@ internal class CborTreeReader(
144144
parser.end()
145145
}
146146

147-
return CborMap(elements, tags)
147+
return CborMap(elements, tags = tags)
148148
}
149149
}

formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/Decoder.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,9 @@ internal open class CborReader(override val cbor: Cbor, protected val parser: Cb
118118
override fun <T> decodeSerializableValue(deserializer: DeserializationStrategy<T>): T {
119119
@Suppress("UNCHECKED_CAST")
120120
return if (deserializer is CborSerializer) {
121-
parser.processTags(tags)
122-
decodeCborElement() as T
123-
}
124-
else if ((decodeByteArrayAsByteString || cbor.configuration.alwaysUseByteString)
121+
val tags = parser.processTags(tags)
122+
decodeCborElement().also { /*this is a NOOP for structured parser but not from bytes */it.tags = tags ?: ulongArrayOf() } as T
123+
} else if ((decodeByteArrayAsByteString || cbor.configuration.alwaysUseByteString)
125124
&& deserializer.descriptor == ByteArraySerializer().descriptor
126125
) {
127126
@Suppress("UNCHECKED_CAST")
@@ -602,7 +601,7 @@ internal class StructuredCborParser(internal val element: CborElement, private v
602601
CborParserInterface {
603602

604603
internal var layer: CborLayer = false to PeekingIterator(element)
605-
private set
604+
private set
606605

607606

608607
private val layerStack = ArrayDeque<CborLayer>()

formats/cbor/commonMain/src/kotlinx/serialization/cbor/internal/Encoder.kt

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ internal sealed class CborWriter(
3838

3939
class Data(val bytes: ByteArrayOutput, var elementCount: Int)
4040

41-
internal abstract fun getDestination(): ByteArrayOutput
41+
protected abstract fun getDestination(): ByteArrayOutput
4242

4343
override val serializersModule: SerializersModule
4444
get() = cbor.serializersModule
@@ -148,7 +148,7 @@ internal sealed class CborWriter(
148148
return true
149149
}
150150

151-
internal fun encodeTag(tag: ULong) = getDestination().encodeTag(tag)
151+
internal abstract fun encodeTags(tags: ULongArray)
152152
}
153153

154154

@@ -183,6 +183,8 @@ internal class IndefiniteLengthCborWriter(cbor: Cbor, private val output: ByteAr
183183
override fun incrementChildren() {/*NOOP*/
184184
}
185185

186+
override fun encodeTags(tags: ULongArray) = tags.forEach { getDestination().encodeTag(it) }
187+
186188
}
187189

188190
// optimized indefinite length encoder
@@ -234,19 +236,19 @@ internal class StructuredCborWriter(cbor: Cbor) : CborWriter(cbor) {
234236

235237
private val stack = ArrayDeque<CborContainer>()
236238
private var currentElement: CborContainer? = null
239+
237240
// value tags are collects inside beginStructure, so we need to cache them here and write them in beginStructure or encodeXXX
238241
// and then null them out, so there are no leftovers
239-
private var nextValueTags : ULongArray = ulongArrayOf()
242+
private var nextValueTags: ULongArray = ulongArrayOf()
240243
get() {
241-
val ret=field
242-
field=ulongArrayOf()
244+
val ret = field
245+
field = ulongArrayOf()
243246
return ret
244247
}
245248

246249
fun finalize() = currentElement!!.finalize()
247250

248251
override fun beginStructure(descriptor: SerialDescriptor): CompositeEncoder {
249-
//TODO check if cborelement and be done
250252
val tags = nextValueTags + (descriptor.getObjectTags() ?: ulongArrayOf())
251253
val element = if (descriptor.hasArrayTag()) {
252254
CborContainer.List(tags)
@@ -270,7 +272,7 @@ internal class StructuredCborWriter(cbor: Cbor) : CborWriter(cbor) {
270272
}
271273
}
272274

273-
override fun getDestination() = throw IllegalStateException("There is not byteArrayOutput")
275+
override fun getDestination() = throw IllegalStateException("There is no byteArrayInput")
274276

275277
override fun incrementChildren() {
276278
/*NOOP*/
@@ -295,67 +297,76 @@ internal class StructuredCborWriter(cbor: Cbor) : CborWriter(cbor) {
295297
if (cbor.configuration.preferCborLabelsOverNames && cborLabel != null) {
296298
currentElement += CborInt(value = cborLabel, tags = keyTags ?: ulongArrayOf())
297299
} else {
298-
currentElement += CborString(name, keyTags ?: ulongArrayOf())
300+
currentElement += CborString(name, tags = keyTags ?: ulongArrayOf())
299301
}
300302
}
301303
}
302304

303305
if (cbor.configuration.encodeValueTags) {
304-
descriptor.getValueTags(index)?.let { valueTags ->
306+
descriptor.getValueTags(index).let { valueTags ->
305307
//collect them for late encoding in beginStructure or encodeXXX
306-
nextValueTags = valueTags?:ulongArrayOf()
308+
nextValueTags = valueTags ?: ulongArrayOf()
307309
}
308310
}
309311
return true
310312
}
311313

314+
315+
override fun encodeTags(tags: ULongArray) {
316+
nextValueTags = tags
317+
}
318+
312319
override fun encodeBoolean(value: Boolean) {
313320
currentElement += CborBoolean(value, nextValueTags)
314321
}
315322

316323
override fun encodeByte(value: Byte) {
317-
currentElement += CborInt(value.toLong(), nextValueTags)
324+
currentElement += CborInt(value.toLong(), tags = nextValueTags)
318325
}
319326

320327
override fun encodeChar(value: Char) {
321-
currentElement += CborInt(value.code.toLong(), nextValueTags)
328+
currentElement += CborInt(value.code.toLong(), tags = nextValueTags)
322329
}
323330

324331
override fun encodeDouble(value: Double) {
325-
currentElement += CborDouble(value, nextValueTags)
332+
currentElement += CborDouble(value, tags = nextValueTags)
326333
}
327334

328335
override fun encodeFloat(value: Float) {
329-
currentElement += CborDouble(value.toDouble(), nextValueTags)
336+
currentElement += CborDouble(value.toDouble(), tags = nextValueTags)
330337
}
331338

332339
override fun encodeInt(value: Int) {
333-
currentElement += CborInt(value.toLong(), nextValueTags)
340+
currentElement += CborInt(value.toLong(), tags = nextValueTags)
334341
}
335342

336343
override fun encodeLong(value: Long) {
337-
currentElement += CborInt(value, nextValueTags)
344+
currentElement += CborInt(value, tags = nextValueTags)
338345
}
339346

340347
override fun encodeShort(value: Short) {
341-
currentElement += CborInt(value.toLong(), nextValueTags)
348+
currentElement += CborInt(value.toLong(), tags = nextValueTags)
342349
}
343350

344351
override fun encodeString(value: String) {
345-
currentElement += CborString(value, nextValueTags)
352+
currentElement += CborString(value, tags = nextValueTags)
346353
}
347354

348355
override fun encodeByteString(byteArray: ByteArray) {
349-
currentElement += CborByteString(byteArray, nextValueTags)
356+
currentElement += CborByteString(byteArray, tags = nextValueTags)
350357
}
351358

352359
override fun encodeNull() {
353-
currentElement += if (isClass) CborMap(mapOf(), nextValueTags) /*NOT CBOR-COMPLIANT, KxS-proprietary behaviour*/
354-
else CborNull(nextValueTags)
360+
/*NOT CBOR-COMPLIANT, KxS-proprietary behaviour*/
361+
currentElement += if (isClass) CborMap(
362+
mapOf(),
363+
tags = nextValueTags
364+
)
365+
else CborNull(tags = nextValueTags)
355366
}
356367

357368
override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) {
358-
currentElement += CborString(enumDescriptor.getElementName(index), nextValueTags)
369+
currentElement += CborString(enumDescriptor.getElementName(index), tags = nextValueTags)
359370
}
360371

361372
}
@@ -372,6 +383,8 @@ internal class DefiniteLengthCborWriter(cbor: Cbor, output: ByteArrayOutput) : C
372383
structureStack.peek().elementCount++
373384
}
374385

386+
override fun encodeTags(tags: ULongArray) = tags.forEach { getDestination().encodeTag(it) }
387+
375388
override fun beginStructure(descriptor: SerialDescriptor): CompositeEncoder {
376389
val current = Data(ByteArrayOutput(), 0)
377390
structureStack.push(current)

0 commit comments

Comments
 (0)