commonMain.io.realm.kotlin.internal.RealmUUIDImpl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of library-base-jvm Show documentation
Show all versions of library-base-jvm Show documentation
Library code for Realm Kotlin. This artifact is not supposed to be consumed directly, but through 'io.realm.kotlin:gradle-plugin:1.11.1' instead.
/*
* Copyright 2022 Realm Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.realm.kotlin.internal
import io.realm.kotlin.internal.platform.SecureRandom
import io.realm.kotlin.internal.util.HEX_PATTERN
import io.realm.kotlin.internal.util.parseHex
import io.realm.kotlin.internal.util.toHexString
import io.realm.kotlin.types.RealmUUID
import org.mongodb.kbson.BsonBinary
import org.mongodb.kbson.BsonBinarySubType
import kotlin.experimental.and
import kotlin.experimental.or
@Suppress("MagicNumber")
// Public as constructor is inlined in accessor converter method (Converters.kt)
public class RealmUUIDImpl : RealmUUID {
override val bytes: ByteArray
public constructor() {
bytes = SecureRandom.nextBytes(UUID_BYTE_SIZE).apply {
// Set uuid to version 4, 6th byte must be 0x4x
this[6] = this[6] and 0x0F.toByte()
this[6] = this[6] or 0x40.toByte()
// Set variant, 8th byte must be 0b10xxxxxx or 0b110xxxxx
this[8] = this[8] and 0x3F.toByte()
this[8] = this[8] or 0x80.toByte()
}
}
public constructor(uuidString: String) {
bytes = parseUUIDString(uuidString)
}
public constructor(byteArray: ByteArray) {
if (byteArray.size != UUID_BYTE_SIZE)
throw IllegalArgumentException("Invalid 'bytes' size ${byteArray.size}, byte array size must be $UUID_BYTE_SIZE")
bytes = byteArray
}
override fun equals(other: Any?): Boolean {
// Check if 'other' is null since type coercion would fail in that case
return when (other) {
null -> false
is RealmUUID -> other.bytes.contentEquals(bytes)
else -> false
}
}
override fun hashCode(): Int {
// We consider two RealmUUID's equal if they have the same byte sequence, so in
// order to match the contract of equals/hashcode on JVM we calculate the hashcode
// as the sum of hashcode of all bytes.
return bytes.contentHashCode()
}
override fun toString(): String {
return bytes.toHexString(0, 4) +
"-" +
bytes.toHexString(4, 6) +
"-" +
bytes.toHexString(6, 8) +
"-" +
bytes.toHexString(8, 10) +
"-" +
bytes.toHexString(10, 16)
}
public companion object {
private const val UUID_BYTE_SIZE = 16
private val UUID_REGEX by lazy {
("($HEX_PATTERN{8})-($HEX_PATTERN{4})-($HEX_PATTERN{4})-($HEX_PATTERN{4})-($HEX_PATTERN{12})").toRegex()
}
/**
* Validates and parses an UUID string representation into a byte array.
*/
private fun parseUUIDString(uuidString: String): ByteArray {
val matchGroup = UUID_REGEX.matchEntire(uuidString)
?: throw IllegalArgumentException("Invalid string representation of an UUID: '$uuidString'")
val byteGroups = (1..5).map { groupIndex ->
matchGroup.groups[groupIndex]!!.value.parseHex()
}
return byteGroups[0] + byteGroups[1] + byteGroups[2] + byteGroups[3] + byteGroups[4]
}
}
}
@Suppress("NOTHING_TO_INLINE")
public inline fun RealmUUID.asBsonBinary(): BsonBinary = BsonBinary(BsonBinarySubType.UUID_STANDARD, bytes)
@Suppress("NOTHING_TO_INLINE")
public inline fun BsonBinary.asRealmUUID(): RealmUUID = RealmUUID.from(data)
© 2015 - 2024 Weber Informatics LLC | Privacy Policy