Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,11 @@ internal val ProtoDesc.integerType: ProtoIntegerType
}

internal val SerialDescriptor.isPackable: Boolean
@OptIn(kotlinx.serialization.ExperimentalSerializationApi::class)
get() = when (kind) {
PrimitiveKind.STRING,
!is PrimitiveKind -> false
else -> true
}
} || isInline && elementsCount == 1 && getElementDescriptor(0).isPackable

internal val ProtoDesc.isPacked: Boolean
get() = (this and PACKEDMASK) != 0L
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ internal open class ProtobufDecoder(

override fun <T> decodeSerializableValue(deserializer: DeserializationStrategy<T>): T = decodeSerializableValue(deserializer, null)

@OptIn(ExperimentalUnsignedTypes::class)
@Suppress("UNCHECKED_CAST")
override fun <T> decodeSerializableValue(deserializer: DeserializationStrategy<T>, previousValue: T?): T = try {
when {
Expand All @@ -250,6 +251,7 @@ internal open class ProtobufDecoder(
}

deserializer.descriptor == ByteArraySerializer().descriptor -> deserializeByteArray(previousValue as ByteArray?) as T
deserializer.descriptor == UByteArraySerializer().descriptor -> deserializeByteArray((previousValue as UByteArray?)?.asByteArray()).asUByteArray() as T
deserializer is AbstractCollectionSerializer<*, *, *> ->
(deserializer as AbstractCollectionSerializer<*, T, *>).merge(this, previousValue)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,13 @@ internal open class ProtobufEncoder(

override fun SerialDescriptor.getTag(index: Int) = extractParameters(index)

@OptIn(ExperimentalUnsignedTypes::class)
override fun <T> encodeSerializableValue(serializer: SerializationStrategy<T>, value: T) = when {
serializer is MapLikeSerializer<*, *, *, *> -> {
serializeMap(serializer as SerializationStrategy<T>, value)
}
serializer.descriptor == ByteArraySerializer().descriptor -> serializeByteArray(value as ByteArray)
serializer.descriptor == UByteArraySerializer().descriptor -> serializeByteArray((value as UByteArray).asByteArray())
else -> serializer.serialize(this, value)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ internal abstract class ProtobufTaggedDecoder : ProtobufTaggedBase(), Decoder, C
}

override fun decodeInline(descriptor: SerialDescriptor): Decoder {
return decodeTaggedInline(popTag(), descriptor)
return decodeTaggedInline(popTagOrDefault(), descriptor)
}

override fun decodeInlineElement(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ internal abstract class ProtobufTaggedEncoder : ProtobufTaggedBase(), Encoder, C
}

override fun encodeInline(descriptor: SerialDescriptor): Encoder {
return encodeTaggedInline(popTag(), descriptor)
return encodeTaggedInline(popTagOrDefault(), descriptor)
}

override fun encodeInlineElement(descriptor: SerialDescriptor, index: Int): Encoder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

@file:OptIn(ExperimentalUnsignedTypes::class)

package kotlinx.serialization.protobuf

import kotlinx.serialization.*
Expand Down Expand Up @@ -57,6 +59,31 @@ class PackedArraySerializerTest {
val i: List<Int>
)

@Serializable
data class PackedUByteCarrier(
@ProtoPacked
val b: UByteArray
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false

other as PackedUByteCarrier

return b.contentEquals(other.b)
}

override fun hashCode(): Int {
return b.contentHashCode()
}
}

@Serializable
data class PackedUintCarrier(
@ProtoPacked
val i: List<UInt>
)

/**
* Test that when packing is specified the array is encoded as packed
*/
Expand Down Expand Up @@ -164,4 +191,33 @@ class PackedArraySerializerTest {
assertEquals(obj, decodedAbsentField)
}

@Test
fun testDecodePackedUnsigned() {
val expectedByteCarrier = PackedUByteCarrier(ubyteArrayOf(1.toUByte(), 2.toUByte(), 128.toUByte()))
val expectedIntCarrier = PackedUintCarrier(listOf(1u, 2u, 3u, 128u))

val byteHex = """0a03010280"""
val intHex = """0a050102038001"""

val decodedBytes = ProtoBuf.decodeFromHexString<PackedUByteCarrier>(byteHex)
val decodedInts = ProtoBuf.decodeFromHexString<PackedUintCarrier>(intHex)

assertEquals(expectedByteCarrier, decodedBytes)
assertEquals(expectedIntCarrier, decodedInts)
}
@Test
fun testEncodePackedUnsigned() {
val byteCarrier = PackedUByteCarrier(ubyteArrayOf(1.toUByte(), 2.toUByte(), 128.toUByte()))
val intCarrier = PackedUintCarrier(listOf(1u, 2u, 3u, 128u))

val expectedByteHex = """0a03010280"""
val expectedIntHex = """0a050102038001"""

val byteHex = ProtoBuf.encodeToHexString(byteCarrier)
val intHex = ProtoBuf.encodeToHexString(intCarrier)

assertEquals(expectedByteHex, byteHex)
assertEquals(expectedIntHex, intHex)
}

}