Virtual type implementations for integer and string types

This commit is contained in:
Andrew Golovashevich 2025-02-23 22:31:44 +03:00
parent 87ff29af5b
commit 30bb10951b
12 changed files with 477 additions and 0 deletions

View File

@ -0,0 +1,27 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
@Suppress("ClassName")
public class FLOAT_32(context: DatabaseType.Provider) : DatabaseType._VirtualType<Float, UInt, U_INT_32>(
wraps = context.U_INT_32,
allowValuesCaching = true
) {
override val name: String = "FLOAT"
override fun _unwrap(w: UInt): Float {
return Float.fromBits(w.toInt())
}
override fun _wrap(w: Float): UInt {
return w.toRawBits().toUInt()
}
override fun _equals(l: Float, r: Float): Boolean {
return l == r
}
override fun _compare(l: Float, r: Float): Int {
return l.compareTo(r)
}
}

View File

@ -0,0 +1,27 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
@Suppress("ClassName")
public class FLOAT_64(context: DatabaseType.Provider) : DatabaseType._VirtualType<Double, ULong, U_INT_64>(
wraps = context.U_INT_64,
allowValuesCaching = true
) {
override val name: String = "FLOAT_64"
override fun _unwrap(w: ULong): Double {
return Double.fromBits(w.toLong())
}
override fun _wrap(w: Double): ULong {
return w.toRawBits().toULong()
}
override fun _equals(l: Double, r: Double): Boolean {
return l == r
}
override fun _compare(l: Double, r: Double): Int {
return l.compareTo(r)
}
}

View File

@ -0,0 +1,121 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
import ru.landgrafhomyak.utility.IntSerializers
@OptIn(ExperimentalUnsignedTypes::class)
public abstract class STRING : DatabaseType._VirtualType<String, UByteArray, DatabaseType.BINARY_DATA> {
public val maxLengthOrNull: UInt?
public val isFixedSize: Boolean
protected constructor(context: DatabaseType.Provider) : super(context.BINARY_DATA, allowValuesCaching = true) {
this.maxLengthOrNull = null
this.isFixedSize = false
}
protected constructor(wrappedType: DatabaseType.BINARY_DATA, maxLength: UInt, isFixedSize: Boolean) : super(wrappedType, allowValuesCaching = true) {
this.maxLengthOrNull = maxLength
this.isFixedSize = isFixedSize
}
override fun _equals(l: String, r: String): Boolean {
return l == r
}
override fun _compare(l: String, r: String): Int {
return l.compareTo(r)
}
public class ASCII : STRING {
public constructor(context: DatabaseType.Provider) : super(context)
public constructor(
context: DatabaseType.Provider,
maxLength: UInt,
isFixedSize: Boolean
) : super(context.BINARY_DATA(maxLength, isFixedSize), maxLength, isFixedSize)
override val name: String = "STRING.ASCII"
override fun _unwrap(w: UByteArray): String {
if (this.maxLengthOrNull != null && (this.isFixedSize && w.size.toUInt() != this.maxLengthOrNull || w.size.toUInt() > this.maxLengthOrNull))
throw RuntimeException("Encoded string has wrong size") // todo
val out = CharArray(w.size)
w.forEachIndexed { i, b ->
if (b >= 128u)
throw RuntimeException("Serialization error: char code greater than 127") // todo
out[i] = Char(b.toUShort())
}
return out.concatToString()
}
override fun _wrap(w: String): UByteArray {
if (this.maxLengthOrNull != null && (this.isFixedSize && w.length.toUInt() != this.maxLengthOrNull || w.length.toUInt() > this.maxLengthOrNull))
throw RuntimeException("String has wrong size") // todo
val out = UByteArray(w.length)
w.forEachIndexed { i, c ->
if (c.code >= 128)
throw RuntimeException("Serialization error: char code greater than 127") // todo
out[i] = c.code.toUByte()
}
return out
}
}
public class UTF8 : STRING {
public constructor(context: DatabaseType.Provider) : super(context)
public constructor(
context: DatabaseType.Provider,
maxLength: UInt,
isFixedSize: Boolean
) : super(context.BINARY_DATA(maxLength * 4u, false), maxLength, isFixedSize)
override val name: String = "STRING.UTF8"
override fun _unwrap(w: UByteArray): String {
if (this.maxLengthOrNull != null && this.isFixedSize && w.size.toUInt() != this.maxLengthOrNull)
throw RuntimeException("Encoded string has wrong size") // todo
val out = w.asByteArray().decodeToString()
if (this.maxLengthOrNull != null && out.length.toUInt() > this.maxLengthOrNull)
throw RuntimeException("Encoded string has wrong size") // todo
return out
}
override fun _wrap(w: String): UByteArray {
if (this.maxLengthOrNull != null && (this.isFixedSize && w.length.toUInt() != this.maxLengthOrNull || w.length.toUInt() > this.maxLengthOrNull))
throw RuntimeException("String has wrong size") // todo
return w.encodeToByteArray().asUByteArray()
}
}
public class UTF16 : STRING {
public constructor(context: DatabaseType.Provider) : super(context)
public constructor(
context: DatabaseType.Provider,
maxLength: UInt,
isFixedSize: Boolean
) : super(context.BINARY_DATA(maxLength * 4u, false), maxLength, isFixedSize)
override val name: String = "STRING.UTF16"
override fun _unwrap(w: UByteArray): String {
val length = w.size.toUInt() / 2u
if (this.maxLengthOrNull != null && (this.isFixedSize && length != this.maxLengthOrNull || length > this.maxLengthOrNull))
throw RuntimeException("Encoded string has wrong size") // todo
return CharArray(length.toInt()) { i -> Char(IntSerializers.decode16beHu(w, i * 2)) }.concatToString()
}
override fun _wrap(w: String): UByteArray {
if (this.maxLengthOrNull != null && (this.isFixedSize && w.length.toUInt() != this.maxLengthOrNull || w.length.toUInt() > this.maxLengthOrNull))
throw RuntimeException("String has wrong size") // todo
val out = UByteArray(w.length * 2)
w.forEachIndexed { i, c ->
IntSerializers.encode16beHu(out, i * 2, c.code.toUShort())
}
return out
}
}
}

View File

@ -0,0 +1,30 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
import ru.landgrafhomyak.utility.IntSerializers
@Suppress("ClassName")
@OptIn(ExperimentalUnsignedTypes::class)
public class S_INT_16(context: DatabaseType.Provider) : DatabaseType._VirtualType<Short, UByteArray, DatabaseType.BINARY_DATA>(
wraps = context.BINARY_DATA(2u, true),
allowValuesCaching = true
) {
override val name: String = "S_INT_16"
override fun _unwrap(w: UByteArray): Short {
return IntSerializers.decode16beH(w, 0)
}
override fun _wrap(w: Short): UByteArray {
return IntSerializers.encode16beH(UByteArray(2), 0, w)
}
override fun _equals(l: Short, r: Short): Boolean {
return l == r
}
override fun _compare(l: Short, r: Short): Int {
return l.compareTo(r)
}
}

View File

@ -0,0 +1,30 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
import ru.landgrafhomyak.utility.IntSerializers
@Suppress("ClassName")
@OptIn(ExperimentalUnsignedTypes::class)
public class S_INT_32(context: DatabaseType.Provider) : DatabaseType._VirtualType<Int, UByteArray, DatabaseType.BINARY_DATA>(
wraps = context.BINARY_DATA(4u, true),
allowValuesCaching = true
) {
override val name: String = "S_INT_32"
override fun _unwrap(w: UByteArray): Int {
return IntSerializers.decode32beI(w, 0)
}
override fun _wrap(w: Int): UByteArray {
return IntSerializers.encode32beI(UByteArray(4), 0, w)
}
override fun _equals(l: Int, r: Int): Boolean {
return l == r
}
override fun _compare(l: Int, r: Int): Int {
return l.compareTo(r)
}
}

View File

@ -0,0 +1,30 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
import ru.landgrafhomyak.utility.IntSerializers
@Suppress("ClassName")
@OptIn(ExperimentalUnsignedTypes::class)
public class S_INT_64(context: DatabaseType.Provider) : DatabaseType._VirtualType<Long, UByteArray, DatabaseType.BINARY_DATA>(
wraps = context.BINARY_DATA(8u, true),
allowValuesCaching = true
) {
override val name: String = "S_INT_64"
override fun _unwrap(w: UByteArray): Long {
return IntSerializers.decode64beL(w, 0)
}
override fun _wrap(w: Long): UByteArray {
return IntSerializers.encode64beL(UByteArray(8), 0, w)
}
override fun _equals(l: Long, r: Long): Boolean {
return l == r
}
override fun _compare(l: Long, r: Long): Int {
return l.compareTo(r)
}
}

View File

@ -0,0 +1,31 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
import ru.landgrafhomyak.utility.IntSerializers
@Suppress("ClassName")
@OptIn(ExperimentalUnsignedTypes::class)
public class S_INT_8(context: DatabaseType.Provider) : DatabaseType._VirtualType<Byte, UByteArray, DatabaseType.BINARY_DATA>(
wraps = context.BINARY_DATA(1u, true),
allowValuesCaching = true
) {
override val name: String = "S_INT_8"
override fun _unwrap(w: UByteArray): Byte {
return IntSerializers.decode8B(w, 0)
}
override fun _wrap(w: Byte): UByteArray {
return IntSerializers.encode8B(UByteArray(1), 0, w)
}
override fun _equals(l: Byte, r: Byte): Boolean {
return l == r
}
override fun _compare(l: Byte, r: Byte): Int {
return l.compareTo(r)
}
}

View File

@ -0,0 +1,30 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
import ru.landgrafhomyak.utility.IntSerializers
@Suppress("ClassName")
@OptIn(ExperimentalUnsignedTypes::class)
public class U_INT_16(context: DatabaseType.Provider) : DatabaseType._VirtualType<UShort, UByteArray, DatabaseType.BINARY_DATA>(
wraps = context.BINARY_DATA(2u, true),
allowValuesCaching = true
) {
override val name: String = "U_INT_16"
override fun _unwrap(w: UByteArray): UShort {
return IntSerializers.decode16beHu(w, 0)
}
override fun _wrap(w: UShort): UByteArray {
return IntSerializers.encode16beHu(UByteArray(2), 0, w)
}
override fun _equals(l: UShort, r: UShort): Boolean {
return l == r
}
override fun _compare(l: UShort, r: UShort): Int {
return l.compareTo(r)
}
}

View File

@ -0,0 +1,30 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
import ru.landgrafhomyak.utility.IntSerializers
@Suppress("ClassName")
@OptIn(ExperimentalUnsignedTypes::class)
public class U_INT_32(context: DatabaseType.Provider) : DatabaseType._VirtualType<UInt, UByteArray, DatabaseType.BINARY_DATA>(
wraps = context.BINARY_DATA(4u, true),
allowValuesCaching = true
) {
override val name: String = "U_INT_32"
override fun _unwrap(w: UByteArray): UInt {
return IntSerializers.decode32beIu(w, 0)
}
override fun _wrap(w: UInt): UByteArray {
return IntSerializers.encode32beIu(UByteArray(4), 0, w)
}
override fun _equals(l: UInt, r: UInt): Boolean {
return l == r
}
override fun _compare(l: UInt, r: UInt): Int {
return l.compareTo(r)
}
}

View File

@ -0,0 +1,30 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
import ru.landgrafhomyak.utility.IntSerializers
@Suppress("ClassName")
@OptIn(ExperimentalUnsignedTypes::class)
public class U_INT_64(context: DatabaseType.Provider) : DatabaseType._VirtualType<ULong, UByteArray, DatabaseType.BINARY_DATA>(
wraps = context.BINARY_DATA(8u, true),
allowValuesCaching = true
) {
override val name: String = "U_INT_64"
override fun _unwrap(w: UByteArray): ULong {
return IntSerializers.decode64beLu(w, 0)
}
override fun _wrap(w: ULong): UByteArray {
return IntSerializers.encode64beLu(UByteArray(8), 0, w)
}
override fun _equals(l: ULong, r: ULong): Boolean {
return l == r
}
override fun _compare(l: ULong, r: ULong): Int {
return l.compareTo(r)
}
}

View File

@ -0,0 +1,30 @@
package ru.landgrafhomyak.db.serdha0.user_commons.types
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
import ru.landgrafhomyak.utility.IntSerializers
@Suppress("ClassName")
@OptIn(ExperimentalUnsignedTypes::class)
public class U_INT_8(context: DatabaseType.Provider) : DatabaseType._VirtualType<UByte, UByteArray, DatabaseType.BINARY_DATA>(
wraps = context.BINARY_DATA(1u, true),
allowValuesCaching = true
) {
override val name: String = "U_INT_8"
override fun _unwrap(w: UByteArray): UByte {
return IntSerializers.decode8Bu(w, 0)
}
override fun _wrap(w: UByte): UByteArray {
return IntSerializers.encode8Bu(UByteArray(1), 0, w)
}
override fun _equals(l: UByte, r: UByte): Boolean {
return l == r
}
override fun _compare(l: UByte, r: UByte): Int {
return l.compareTo(r)
}
}

View File

@ -0,0 +1,61 @@
@file:JvmName("_ProviderExtensionKt")
package ru.landgrafhomyak.db.serdha0.user_commons.types
import kotlin.jvm.JvmName
import ru.landgrafhomyak.db.serdha0.api.misc.DatabaseType
@get:JvmName("U_INT_8")
public val DatabaseType.Provider.U_INT_8: U_INT_8 get() = U_INT_8(this)
@get:JvmName("U_INT_16")
public val DatabaseType.Provider.U_INT_16: U_INT_16 get() = U_INT_16(this)
@get:JvmName("U_INT_32")
public val DatabaseType.Provider.U_INT_32: U_INT_32 get() = U_INT_32(this)
@get:JvmName("U_INT_64")
public val DatabaseType.Provider.U_INT_64: U_INT_64 get() = U_INT_64(this)
@get:JvmName("S_INT_8")
public val DatabaseType.Provider.S_INT_8: S_INT_8 get() = S_INT_8(this)
@get:JvmName("S_INT_16")
public val DatabaseType.Provider.S_INT_16: S_INT_16 get() = S_INT_16(this)
@get:JvmName("S_INT_32")
public val DatabaseType.Provider.S_INT_32: S_INT_32 get() = S_INT_32(this)
@get:JvmName("S_INT_64")
public val DatabaseType.Provider.S_INT_64: S_INT_64 get() = S_INT_64(this)
@get:JvmName("FLOAT_32")
public val DatabaseType.Provider.FLOAT_32: FLOAT_32 get() = FLOAT_32(this)
@get:JvmName("FLOAT_64")
public val DatabaseType.Provider.FLOAT_64: FLOAT_64 get() = FLOAT_64(this)
@Suppress("ClassName", "PropertyName")
public class _StringTypesProvider internal constructor(private val _context: DatabaseType.Provider) {
@get:JvmName("ASCII")
public val ASCII: STRING.ASCII get() = STRING.ASCII(this._context)
public fun ASCII(length: UInt, isFixedSize: Boolean): STRING.ASCII = STRING.ASCII(this._context, length, isFixedSize)
@get:JvmName("UTF8")
public val UTF8: STRING.UTF8 get() = STRING.UTF8(this._context)
public fun UTF8(length: UInt, isFixedSize: Boolean): STRING.UTF8 = STRING.UTF8(this._context, length, isFixedSize)
@get:JvmName("UTF16")
public val UTF16: STRING.UTF16 get() = STRING.UTF16(this._context)
public fun UTF16(length: UInt, isFixedSize: Boolean): STRING.UTF16 = STRING.UTF16(this._context, length, isFixedSize)
public companion object {
@Suppress("FunctionName")
public fun _getContext(t: _StringTypesProvider): DatabaseType.Provider = t._context
}
}
@get:JvmName("FLOAT_64")
public val DatabaseType.Provider.STRING: _StringTypesProvider get() = _StringTypesProvider(this)