Skip to content

Commit

Permalink
Added support for the unsigned primitives and arrays as built-in
Browse files Browse the repository at this point in the history
Fixes #1745
Fixes #1480
Resolves #1989
  • Loading branch information
shanshin committed Sep 22, 2022
1 parent 9658ea7 commit e311eb8
Show file tree
Hide file tree
Showing 7 changed files with 437 additions and 0 deletions.
60 changes: 60 additions & 0 deletions core/api/kotlinx-serialization-core.api
Expand Up @@ -170,6 +170,10 @@ public final class kotlinx/serialization/builtins/BuiltinSerializersKt {
public static final fun SetSerializer (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;
public static final fun ShortArraySerializer ()Lkotlinx/serialization/KSerializer;
public static final fun TripleSerializer (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;
public static final fun UByteArraySerializer ()Lkotlinx/serialization/KSerializer;
public static final fun UIntArraySerializer ()Lkotlinx/serialization/KSerializer;
public static final fun ULongArraySerializer ()Lkotlinx/serialization/KSerializer;
public static final fun UShortArraySerializer ()Lkotlinx/serialization/KSerializer;
public static final fun getNullable (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer;
public static final fun serializer (Lkotlin/UByte$Companion;)Lkotlinx/serialization/KSerializer;
public static final fun serializer (Lkotlin/UInt$Companion;)Lkotlinx/serialization/KSerializer;
Expand Down Expand Up @@ -1151,6 +1155,20 @@ public final class kotlinx/serialization/internal/TripleSerializer : kotlinx/ser
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lkotlin/Triple;)V
}

public final class kotlinx/serialization/internal/UByteArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder {
public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object;
}

public final class kotlinx/serialization/internal/UByteArraySerializer : kotlinx/serialization/internal/PrimitiveArraySerializer, kotlinx/serialization/KSerializer {
public static final field INSTANCE Lkotlinx/serialization/internal/UByteArraySerializer;
public synthetic fun collectionSize (Ljava/lang/Object;)I
public synthetic fun empty ()Ljava/lang/Object;
public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILjava/lang/Object;Z)V
public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILkotlinx/serialization/internal/PrimitiveArrayBuilder;Z)V
public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object;
public synthetic fun writeContent (Lkotlinx/serialization/encoding/CompositeEncoder;Ljava/lang/Object;I)V
}

public final class kotlinx/serialization/internal/UByteSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Lkotlinx/serialization/internal/UByteSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
Expand All @@ -1160,6 +1178,20 @@ public final class kotlinx/serialization/internal/UByteSerializer : kotlinx/seri
public fun serialize-EK-6454 (Lkotlinx/serialization/encoding/Encoder;B)V
}

public final class kotlinx/serialization/internal/UIntArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder {
public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object;
}

public final class kotlinx/serialization/internal/UIntArraySerializer : kotlinx/serialization/internal/PrimitiveArraySerializer, kotlinx/serialization/KSerializer {
public static final field INSTANCE Lkotlinx/serialization/internal/UIntArraySerializer;
public synthetic fun collectionSize (Ljava/lang/Object;)I
public synthetic fun empty ()Ljava/lang/Object;
public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILjava/lang/Object;Z)V
public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILkotlinx/serialization/internal/PrimitiveArrayBuilder;Z)V
public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object;
public synthetic fun writeContent (Lkotlinx/serialization/encoding/CompositeEncoder;Ljava/lang/Object;I)V
}

public final class kotlinx/serialization/internal/UIntSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Lkotlinx/serialization/internal/UIntSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
Expand All @@ -1169,6 +1201,20 @@ public final class kotlinx/serialization/internal/UIntSerializer : kotlinx/seria
public fun serialize-Qn1smSk (Lkotlinx/serialization/encoding/Encoder;I)V
}

public final class kotlinx/serialization/internal/ULongArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder {
public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object;
}

public final class kotlinx/serialization/internal/ULongArraySerializer : kotlinx/serialization/internal/PrimitiveArraySerializer, kotlinx/serialization/KSerializer {
public static final field INSTANCE Lkotlinx/serialization/internal/ULongArraySerializer;
public synthetic fun collectionSize (Ljava/lang/Object;)I
public synthetic fun empty ()Ljava/lang/Object;
public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILjava/lang/Object;Z)V
public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILkotlinx/serialization/internal/PrimitiveArrayBuilder;Z)V
public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object;
public synthetic fun writeContent (Lkotlinx/serialization/encoding/CompositeEncoder;Ljava/lang/Object;I)V
}

public final class kotlinx/serialization/internal/ULongSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Lkotlinx/serialization/internal/ULongSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
Expand All @@ -1178,6 +1224,20 @@ public final class kotlinx/serialization/internal/ULongSerializer : kotlinx/seri
public fun serialize-2TYgG_w (Lkotlinx/serialization/encoding/Encoder;J)V
}

public final class kotlinx/serialization/internal/UShortArrayBuilder : kotlinx/serialization/internal/PrimitiveArrayBuilder {
public synthetic fun build$kotlinx_serialization_core ()Ljava/lang/Object;
}

public final class kotlinx/serialization/internal/UShortArraySerializer : kotlinx/serialization/internal/PrimitiveArraySerializer, kotlinx/serialization/KSerializer {
public static final field INSTANCE Lkotlinx/serialization/internal/UShortArraySerializer;
public synthetic fun collectionSize (Ljava/lang/Object;)I
public synthetic fun empty ()Ljava/lang/Object;
public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILjava/lang/Object;Z)V
public synthetic fun readElement (Lkotlinx/serialization/encoding/CompositeDecoder;ILkotlinx/serialization/internal/PrimitiveArrayBuilder;Z)V
public synthetic fun toBuilder (Ljava/lang/Object;)Ljava/lang/Object;
public synthetic fun writeContent (Lkotlinx/serialization/encoding/CompositeEncoder;Ljava/lang/Object;I)V
}

public final class kotlinx/serialization/internal/UShortSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Lkotlinx/serialization/internal/UShortSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
Expand Down
Expand Up @@ -74,6 +74,14 @@ public fun Byte.Companion.serializer(): KSerializer<Byte> = ByteSerializer
*/
public fun ByteArraySerializer(): KSerializer<ByteArray> = ByteArraySerializer

/**
* Returns serializer for [UByteArray] with [descriptor][SerialDescriptor] of [StructureKind.LIST] kind.
* Each element of the array is serialized one by one with [UByte.Companion.serializer].
*/
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
public fun UByteArraySerializer(): KSerializer<UByteArray> = UByteArraySerializer

/**
* Returns serializer for [Short] with [descriptor][SerialDescriptor] of [PrimitiveKind.SHORT] kind.
*/
Expand All @@ -85,6 +93,14 @@ public fun Short.Companion.serializer(): KSerializer<Short> = ShortSerializer
*/
public fun ShortArraySerializer(): KSerializer<ShortArray> = ShortArraySerializer

/**
* Returns serializer for [UShortArray] with [descriptor][SerialDescriptor] of [StructureKind.LIST] kind.
* Each element of the array is serialized one by one with [UShort.Companion.serializer].
*/
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
public fun UShortArraySerializer(): KSerializer<UShortArray> = UShortArraySerializer

/**
* Returns serializer for [Int] with [descriptor][SerialDescriptor] of [PrimitiveKind.INT] kind.
*/
Expand All @@ -96,6 +112,14 @@ public fun Int.Companion.serializer(): KSerializer<Int> = IntSerializer
*/
public fun IntArraySerializer(): KSerializer<IntArray> = IntArraySerializer

/**
* Returns serializer for [UIntArray] with [descriptor][SerialDescriptor] of [StructureKind.LIST] kind.
* Each element of the array is serialized one by one with [UInt.Companion.serializer].
*/
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
public fun UIntArraySerializer(): KSerializer<UIntArray> = UIntArraySerializer

/**
* Returns serializer for [Long] with [descriptor][SerialDescriptor] of [PrimitiveKind.LONG] kind.
*/
Expand All @@ -107,6 +131,14 @@ public fun Long.Companion.serializer(): KSerializer<Long> = LongSerializer
*/
public fun LongArraySerializer(): KSerializer<LongArray> = LongArraySerializer

/**
* Returns serializer for [ULongArray] with [descriptor][SerialDescriptor] of [StructureKind.LIST] kind.
* Each element of the array is serialized one by one with [ULong.Companion.serializer].
*/
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
public fun ULongArraySerializer(): KSerializer<ULongArray> = ULongArraySerializer

/**
* Returns serializer for [Float] with [descriptor][SerialDescriptor] of [PrimitiveKind.FLOAT] kind.
*/
Expand Down
Expand Up @@ -408,3 +408,223 @@ internal class BooleanArrayBuilder internal constructor(

override fun build() = buffer.copyOf(position)
}


// Unsigned arrays

/**
* Serializer for [UByteArray].
*
* Encode elements one-by-one, as regular list,
* unless format's Encoder/Decoder have special handling for this serializer.
*/
@PublishedApi
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
internal object UByteArraySerializer : KSerializer<UByteArray>,
PrimitiveArraySerializer<UByte, UByteArray, UByteArrayBuilder>(UByte.serializer()) {

override fun UByteArray.collectionSize(): Int = size
override fun UByteArray.toBuilder(): UByteArrayBuilder = UByteArrayBuilder(this)
override fun empty(): UByteArray = UByteArray(0)

override fun readElement(decoder: CompositeDecoder, index: Int, builder: UByteArrayBuilder, checkIndex: Boolean) {
builder.append(decoder.decodeInlineElement(descriptor, index).decodeByte().toUByte())
}

override fun writeContent(encoder: CompositeEncoder, content: UByteArray, size: Int) {
for (i in 0 until size)
encoder.encodeInlineElement(descriptor, i).encodeByte(content[i].toByte())
}
}

@PublishedApi
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
internal class UByteArrayBuilder internal constructor(
bufferWithData: UByteArray
) : PrimitiveArrayBuilder<UByteArray>() {

private var buffer: UByteArray = bufferWithData
override var position: Int = bufferWithData.size
private set

init {
ensureCapacity(INITIAL_SIZE)
}

override fun ensureCapacity(requiredCapacity: Int) {
if (buffer.size < requiredCapacity)
buffer = buffer.copyOf(requiredCapacity.coerceAtLeast(buffer.size * 2))
}

internal fun append(c: UByte) {
ensureCapacity()
buffer[position++] = c
}

override fun build() = buffer.copyOf(position)
}

/**
* Serializer for [UShortArray].
*
* Encode elements one-by-one, as regular list,
* unless format's Encoder/Decoder have special handling for this serializer.
*/
@PublishedApi
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
internal object UShortArraySerializer : KSerializer<UShortArray>,
PrimitiveArraySerializer<UShort, UShortArray, UShortArrayBuilder>(UShort.serializer()) {

override fun UShortArray.collectionSize(): Int = size
override fun UShortArray.toBuilder(): UShortArrayBuilder = UShortArrayBuilder(this)
override fun empty(): UShortArray = UShortArray(0)

override fun readElement(decoder: CompositeDecoder, index: Int, builder: UShortArrayBuilder, checkIndex: Boolean) {
builder.append(decoder.decodeInlineElement(descriptor, index).decodeShort().toUShort())
}

override fun writeContent(encoder: CompositeEncoder, content: UShortArray, size: Int) {
for (i in 0 until size)
encoder.encodeInlineElement(descriptor, i).encodeShort(content[i].toShort())
}
}

@PublishedApi
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
internal class UShortArrayBuilder internal constructor(
bufferWithData: UShortArray
) : PrimitiveArrayBuilder<UShortArray>() {

private var buffer: UShortArray = bufferWithData
override var position: Int = bufferWithData.size
private set

init {
ensureCapacity(INITIAL_SIZE)
}

override fun ensureCapacity(requiredCapacity: Int) {
if (buffer.size < requiredCapacity)
buffer = buffer.copyOf(requiredCapacity.coerceAtLeast(buffer.size * 2))
}

internal fun append(c: UShort) {
ensureCapacity()
buffer[position++] = c
}

override fun build() = buffer.copyOf(position)
}

/**
* Serializer for [UIntArray].
*
* Encode elements one-by-one, as regular list,
* unless format's Encoder/Decoder have special handling for this serializer.
*/
@PublishedApi
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
internal object UIntArraySerializer : KSerializer<UIntArray>,
PrimitiveArraySerializer<UInt, UIntArray, UIntArrayBuilder>(UInt.serializer()) {

override fun UIntArray.collectionSize(): Int = size
override fun UIntArray.toBuilder(): UIntArrayBuilder = UIntArrayBuilder(this)
override fun empty(): UIntArray = UIntArray(0)

override fun readElement(decoder: CompositeDecoder, index: Int, builder: UIntArrayBuilder, checkIndex: Boolean) {
builder.append(decoder.decodeInlineElement(descriptor, index).decodeInt().toUInt())
}

override fun writeContent(encoder: CompositeEncoder, content: UIntArray, size: Int) {
for (i in 0 until size)
encoder.encodeInlineElement(descriptor, i).encodeInt(content[i].toInt())
}
}

@PublishedApi
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
internal class UIntArrayBuilder internal constructor(
bufferWithData: UIntArray
) : PrimitiveArrayBuilder<UIntArray>() {

private var buffer: UIntArray = bufferWithData
override var position: Int = bufferWithData.size
private set

init {
ensureCapacity(INITIAL_SIZE)
}

override fun ensureCapacity(requiredCapacity: Int) {
if (buffer.size < requiredCapacity)
buffer = buffer.copyOf(requiredCapacity.coerceAtLeast(buffer.size * 2))
}

internal fun append(c: UInt) {
ensureCapacity()
buffer[position++] = c
}

override fun build() = buffer.copyOf(position)
}

/**
* Serializer for [ULongArray].
*
* Encode elements one-by-one, as regular list,
* unless format's Encoder/Decoder have special handling for this serializer.
*/
@PublishedApi
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
internal object ULongArraySerializer : KSerializer<ULongArray>,
PrimitiveArraySerializer<ULong, ULongArray, ULongArrayBuilder>(ULong.serializer()) {

override fun ULongArray.collectionSize(): Int = size
override fun ULongArray.toBuilder(): ULongArrayBuilder = ULongArrayBuilder(this)
override fun empty(): ULongArray = ULongArray(0)

override fun readElement(decoder: CompositeDecoder, index: Int, builder: ULongArrayBuilder, checkIndex: Boolean) {
builder.append(decoder.decodeInlineElement(descriptor, index).decodeLong().toULong())
}

override fun writeContent(encoder: CompositeEncoder, content: ULongArray, size: Int) {
for (i in 0 until size)
encoder.encodeInlineElement(descriptor, i).encodeLong(content[i].toLong())
}
}

@PublishedApi
@ExperimentalSerializationApi
@ExperimentalUnsignedTypes
internal class ULongArrayBuilder internal constructor(
bufferWithData: ULongArray
) : PrimitiveArrayBuilder<ULongArray>() {

private var buffer: ULongArray = bufferWithData
override var position: Int = bufferWithData.size
private set

init {
ensureCapacity(INITIAL_SIZE)
}

override fun ensureCapacity(requiredCapacity: Int) {
if (buffer.size < requiredCapacity)
buffer = buffer.copyOf(requiredCapacity.coerceAtLeast(buffer.size * 2))
}

internal fun append(c: ULong) {
ensureCapacity()
buffer[position++] = c
}

override fun build() = buffer.copyOf(position)
}

0 comments on commit e311eb8

Please sign in to comment.