Skip to content
Merged
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
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
javaVersion=25
mcVersion=26.3
group=dev.slne.surf.api
version=3.46.2
version=3.47.0
relocationPrefix=dev.slne.surf.api.libs
snapshot=false
9 changes: 9 additions & 0 deletions surf-api-core/surf-api-core/api/surf-api-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -10457,6 +10457,15 @@ public final class dev/slne/surf/api/core/serializer/java/url/URLSerializer : ko
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/net/URL;)V
}

public final class dev/slne/surf/api/core/serializer/java/uuid/JavaUUIDLongSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Ldev/slne/surf/api/core/serializer/java/uuid/JavaUUIDLongSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/util/UUID;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/util/UUID;)V
}

public final class dev/slne/surf/api/core/serializer/java/uuid/JavaUUIDSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Ldev/slne/surf/api/core/serializer/java/uuid/JavaUUIDSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package dev.slne.surf.api.core.serializer.java.uuid

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.descriptors.element
import kotlinx.serialization.encoding.*
import java.util.*

typealias SerializableLongUUID = @Serializable(with = JavaUUIDLongSerializer::class) UUID

object JavaUUIDLongSerializer : KSerializer<UUID> {
override val descriptor = buildClassSerialDescriptor("surf.api.LongUuid") {
element<Long>("most")
element<Long>("least")
}

override fun serialize(encoder: Encoder, value: UUID) {
encoder.encodeStructure(descriptor) {
encodeLongElement(descriptor, 0, value.mostSignificantBits)
encodeLongElement(descriptor, 1, value.leastSignificantBits)
}
}

@OptIn(ExperimentalSerializationApi::class)
override fun deserialize(decoder: Decoder): UUID = decoder.decodeStructure(descriptor) {
if (decodeSequentially()) {
return@decodeStructure UUID(
decodeLongElement(descriptor, 0),
decodeLongElement(descriptor, 1),
)
}

var most = 0L
var least = 0L
var seen = 0
while (true) {
when (val index = decodeElementIndex(descriptor)) {
0 -> {
most = decodeLongElement(descriptor, 0)
seen = seen or 1
}

1 -> {
least = decodeLongElement(descriptor, 1)
seen = seen or 2
}

CompositeDecoder.DECODE_DONE -> break
else -> throw SerializationException("Unexpected element index $index")
}
}

if (seen != 3) throw SerializationException("UUID requires both 'most' and 'least'")

UUID(most, least)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,39 @@ package dev.slne.surf.api.core.serializer.java.uuid
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.ByteArraySerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.nio.ByteBuffer
import java.lang.invoke.MethodHandles
import java.nio.ByteOrder
import java.util.*

typealias SerializableUUID = @Serializable(with = JavaUUIDSerializer::class) UUID

object JavaUUIDSerializer : KSerializer<UUID> {
private val byteArraySerializer = ByteArraySerializer()
override val descriptor = byteArraySerializer.descriptor
private val longBigEndian = MethodHandles.byteArrayViewVarHandle(
LongArray::class.java,
ByteOrder.BIG_ENDIAN,
)

override val descriptor = SerialDescriptor("surf.api.UUID", byteArraySerializer.descriptor)

override fun serialize(encoder: Encoder, value: UUID) {
val bytes = ByteArray(16)
val buffer = ByteBuffer.wrap(bytes)
buffer.putLong(value.mostSignificantBits)
buffer.putLong(value.leastSignificantBits)
longBigEndian.set(bytes, 0, value.mostSignificantBits)
longBigEndian.set(bytes, 8, value.leastSignificantBits)

encoder.encodeSerializableValue(byteArraySerializer, bytes)
}

override fun deserialize(decoder: Decoder): UUID {
val bytes = decoder.decodeSerializableValue(byteArraySerializer)
val buffer = ByteBuffer.wrap(bytes)
val mostSigBits = buffer.long
val leastSigBits = buffer.long
require(bytes.size == 16) { "UUID must be 16 bytes, but was ${bytes.size}" }

val mostSigBits = longBigEndian.get(bytes, 0) as Long
val leastSigBits = longBigEndian.get(bytes, 8) as Long

return UUID(mostSigBits, leastSigBits)
}
}
}
Loading