Skip to content

Commit ff58d2e

Browse files
committed
Add initial decimal128 implementation
1 parent a02722e commit ff58d2e

File tree

24 files changed

+226
-4
lines changed

24 files changed

+226
-4
lines changed

packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/MemAllocator.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
package io.realm.kotlin.internal.interop
2020

21+
import org.mongodb.kbson.Decimal128
2122
import kotlin.jvm.JvmName
2223

2324
/**
@@ -57,10 +58,15 @@ interface MemAllocator {
5758
fun floatTransport(value: Float?): RealmValue
5859

5960
/**
60-
* Instantiates a [RealmValue] representing a `realm_value_t` of type `RLM_TYPE_TIMESTAMP`.
61+
* Instantiates a [RealmValue] representing a `realm_value_t` of type `RLM_TYPE_DOUBLE`.
6162
*/
6263
fun doubleTransport(value: Double?): RealmValue
6364

65+
/**
66+
* Instantiates a [RealmValue] representing a `realm_value_t` of type `RLM_TYPE_DECIMAL128`.
67+
*/
68+
fun decimal128Transport(value: ULongArray?): RealmValue
69+
6470
/**
6571
* Instantiates a [RealmValue] representing a `realm_value_t` of type `RLM_TYPE_OBJECT_ID` from
6672
* an ObjectId's bytes.

packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmEnums.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ expect enum class PropertyType {
4141
RLM_PROPERTY_TYPE_OBJECT,
4242
RLM_PROPERTY_TYPE_FLOAT,
4343
RLM_PROPERTY_TYPE_DOUBLE,
44+
RLM_PROPERTY_TYPE_DECIMAL128,
4445
RLM_PROPERTY_TYPE_TIMESTAMP,
4546
RLM_PROPERTY_TYPE_OBJECT_ID,
4647
RLM_PROPERTY_TYPE_UUID,

packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmValue.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package io.realm.kotlin.internal.interop
1818

19+
import org.mongodb.kbson.Decimal128
20+
1921
/**
2022
* Representation of a C-API `realm_value_t` struct.
2123
*/
@@ -36,6 +38,7 @@ expect value class RealmValue(val value: RealmValueT) {
3638
inline fun getTimestamp(): Timestamp
3739
inline fun getFloat(): Float
3840
inline fun getDouble(): Double
41+
inline fun getDecimal128Array(): ULongArray
3942
inline fun getObjectIdBytes(): ByteArray
4043
inline fun getUUIDBytes(): ByteArray
4144
inline fun getLink(): Link

packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/PropertyType.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ actual enum class PropertyType(override val nativeValue: Int) : NativeEnumerated
2727
RLM_PROPERTY_TYPE_OBJECT(realm_property_type_e.RLM_PROPERTY_TYPE_OBJECT),
2828
RLM_PROPERTY_TYPE_FLOAT(realm_property_type_e.RLM_PROPERTY_TYPE_FLOAT),
2929
RLM_PROPERTY_TYPE_DOUBLE(realm_property_type_e.RLM_PROPERTY_TYPE_DOUBLE),
30+
RLM_PROPERTY_TYPE_DECIMAL128(realm_property_type_e.RLM_PROPERTY_TYPE_DECIMAL128),
3031
RLM_PROPERTY_TYPE_TIMESTAMP(realm_property_type_e.RLM_PROPERTY_TYPE_TIMESTAMP),
3132
RLM_PROPERTY_TYPE_OBJECT_ID(realm_property_type_e.RLM_PROPERTY_TYPE_OBJECT_ID),
3233
RLM_PROPERTY_TYPE_UUID(realm_property_type_e.RLM_PROPERTY_TYPE_UUID),

packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmValue.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package io.realm.kotlin.internal.interop
1818

19+
import org.mongodb.kbson.Decimal128
20+
1921
// TODO BENCHMARK: investigate performance between using this as value vs reference type
2022
actual typealias RealmValueT = realm_value_t
2123

@@ -33,6 +35,13 @@ actual value class RealmValue actual constructor(
3335
actual inline fun getTimestamp(): Timestamp = value.asTimestamp()
3436
actual inline fun getFloat(): Float = value.fnum
3537
actual inline fun getDouble(): Double = value.dnum
38+
actual inline fun getDecimal128Array(): ULongArray {
39+
val decimal128 = value.decimal128
40+
val w = decimal128.w
41+
val toULongArray = w.toULongArray()
42+
return toULongArray
43+
}
44+
3645
actual inline fun getObjectIdBytes(): ByteArray = ByteArray(OBJECT_ID_BYTES_SIZE).also {
3746
value.object_id.bytes.mapIndexed { index, b -> it[index] = b.toByte() }
3847
}
@@ -55,6 +64,7 @@ actual value class RealmValue actual constructor(
5564
ValueType.RLM_TYPE_TIMESTAMP -> getTimestamp().toString()
5665
ValueType.RLM_TYPE_FLOAT -> getFloat()
5766
ValueType.RLM_TYPE_DOUBLE -> getDouble()
67+
ValueType.RLM_TYPE_DECIMAL128 -> getDecimal128Array().toString()
5868
ValueType.RLM_TYPE_OBJECT_ID -> getObjectIdBytes().toString()
5969
ValueType.RLM_TYPE_LINK -> getLink().toString()
6070
ValueType.RLM_TYPE_UUID -> getUUIDBytes().toString()

packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmValueAllocator.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package io.realm.kotlin.internal.interop
1818

1919
import io.realm.kotlin.internal.interop.RealmInterop.cptr
20+
import org.mongodb.kbson.Decimal128
2021

2122
/**
2223
* Singleton object as we just rely on GC'ed realm_value_ts and don't keep track of the actual
@@ -50,6 +51,14 @@ object JvmMemAllocator : MemAllocator {
5051
override fun doubleTransport(value: Double?): RealmValue =
5152
createTransport(value, realm_value_type_e.RLM_TYPE_DOUBLE) { dnum = value!! }
5253

54+
@ExperimentalUnsignedTypes
55+
override fun decimal128Transport(value: ULongArray?): RealmValue =
56+
createTransport(value, realm_value_type_e.RLM_TYPE_DECIMAL128) {
57+
decimal128 = realm_decimal128_t().apply {
58+
w = value!!.toLongArray()
59+
}
60+
}
61+
5362
override fun objectIdTransport(value: ByteArray?): RealmValue =
5463
createTransport(value, realm_value_type_e.RLM_TYPE_OBJECT_ID) {
5564
object_id = realm_object_id_t().apply {

packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmEnums.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ actual enum class PropertyType(override val nativeValue: UInt) : NativeEnumerate
5858
RLM_PROPERTY_TYPE_OBJECT(realm_wrapper.RLM_PROPERTY_TYPE_OBJECT),
5959
RLM_PROPERTY_TYPE_FLOAT(realm_wrapper.RLM_PROPERTY_TYPE_FLOAT),
6060
RLM_PROPERTY_TYPE_DOUBLE(realm_wrapper.RLM_PROPERTY_TYPE_DOUBLE),
61+
RLM_PROPERTY_TYPE_DECIMAL128(realm_wrapper.RLM_PROPERTY_TYPE_DECIMAL128),
6162
RLM_PROPERTY_TYPE_TIMESTAMP(realm_wrapper.RLM_PROPERTY_TYPE_TIMESTAMP),
6263
RLM_PROPERTY_TYPE_OBJECT_ID(realm_wrapper.RLM_PROPERTY_TYPE_OBJECT_ID),
6364
RLM_PROPERTY_TYPE_UUID(realm_wrapper.RLM_PROPERTY_TYPE_UUID),

packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmValue.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package io.realm.kotlin.internal.interop
1919
import kotlinx.cinterop.addressOf
2020
import kotlinx.cinterop.memScoped
2121
import kotlinx.cinterop.usePinned
22+
import org.mongodb.kbson.Decimal128
2223
import platform.posix.memcpy
2324
import realm_wrapper.realm_query_arg
2425
import realm_wrapper.realm_value
@@ -38,6 +39,12 @@ actual value class RealmValue actual constructor(
3839
actual inline fun getTimestamp(): Timestamp = value.asTimestamp()
3940
actual inline fun getFloat(): Float = value.fnum
4041
actual inline fun getDouble(): Double = value.dnum
42+
actual inline fun getDecimal128Array(): ULongArray = ULongArray(2).apply {
43+
(0 until 2).map {
44+
this[it] = value.decimal128.w[it].toULong()
45+
}
46+
}
47+
4148
actual inline fun getObjectIdBytes(): ByteArray = memScoped {
4249
UByteArray(OBJECT_ID_BYTES_SIZE).let { byteArray ->
4350
byteArray.usePinned {
@@ -74,6 +81,7 @@ actual value class RealmValue actual constructor(
7481
ValueType.RLM_TYPE_TIMESTAMP -> getTimestamp().toString()
7582
ValueType.RLM_TYPE_FLOAT -> getFloat()
7683
ValueType.RLM_TYPE_DOUBLE -> getDouble()
84+
ValueType.RLM_TYPE_DECIMAL128 -> getDecimal128Array().toString()
7785
ValueType.RLM_TYPE_OBJECT_ID -> getObjectIdBytes().toString()
7886
ValueType.RLM_TYPE_LINK -> getLink().toString()
7987
ValueType.RLM_TYPE_UUID -> getUUIDBytes().toString()

packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmValueAllocator.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import kotlinx.cinterop.ptr
2828
import kotlinx.cinterop.set
2929
import kotlinx.cinterop.useContents
3030
import kotlinx.cinterop.usePinned
31+
import org.mongodb.kbson.Decimal128
3132
import platform.posix.memcpy
3233
import realm_wrapper.realm_query_arg_t
3334
import realm_wrapper.realm_value_t
@@ -66,6 +67,18 @@ class NativeMemAllocator : MemTrackingAllocator {
6667
override fun doubleTransport(value: Double?): RealmValue =
6768
createTransport(value, realm_value_type.RLM_TYPE_DOUBLE) { dnum = value!! }
6869

70+
@OptIn(ExperimentalUnsignedTypes::class)
71+
override fun decimal128Transport(value: ULongArray?): RealmValue =
72+
createTransport(value, realm_value_type.RLM_TYPE_DECIMAL128) {
73+
decimal128.apply {
74+
value!!.usePinned {
75+
val dest = w.getPointer(scope)
76+
val source = it.addressOf(0)
77+
memcpy(dest, source, 2.toULong())
78+
}
79+
}
80+
}
81+
6982
override fun objectIdTransport(value: ByteArray?): RealmValue =
7083
createTransport(value, realm_value_type.RLM_TYPE_OBJECT_ID) {
7184
object_id.apply {

packages/jni-swig-stub/realm.i

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,13 @@ bool realm_object_is_valid(const realm_object_t*);
323323
// Enable passing uint8_t [64] parameter for realm_sync_client_config_set_metadata_encryption_key as Byte[]
324324
%apply int8_t[] {uint8_t [64]};
325325

326+
// Enable passing uint8_t [2] parameter for realm_decimal128 as Long[]
327+
%apply int64_t[] {uint64_t w[2]};
328+
329+
%typemap(out) uint64_t w[2] %{
330+
$result = SWIG_JavaArrayOutLonglong(jenv, (long long *)result, 2);
331+
%}
332+
326333
%typemap(freearg) const uint8_t* data;
327334
%typemap(out) const uint8_t* data %{
328335
$result = SWIG_JavaArrayOutSchar(jenv, (signed char *)result, arg1->size);

0 commit comments

Comments
 (0)