-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce multiplatform Uuid type #KT-31880
- Loading branch information
1 parent
3f10b2d
commit 25ea5e8
Showing
21 changed files
with
1,500 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. | ||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdarg.h> | ||
|
||
#if KONAN_MACOSX || KONAN_IOS || KONAN_TVOS || KONAN_WATCHOS || KONAN_ANDROID | ||
#include <stdlib.h> | ||
#elif KONAN_LINUX | ||
#include <unistd.h> | ||
#include <sys/syscall.h> | ||
#include <errno.h> | ||
#elif KONAN_WINDOWS | ||
#include <windows.h> | ||
#include <bcrypt.h> | ||
#include <ntdef.h> | ||
#endif | ||
|
||
#include "KString.h" | ||
#include "Exceptions.h" | ||
#include "Format.h" | ||
#include "Memory.h" | ||
#include "Natives.h" | ||
|
||
namespace { | ||
|
||
#if KONAN_LINUX || KONAN_WINDOWS | ||
void throwReadingRandomBytesFailed(const char* format, ...) { | ||
va_list args; | ||
va_start(args, format); | ||
std::array<char, 128> buffer; | ||
kotlin::std_support::span<char> span(buffer); | ||
span = kotlin::VFormatToSpan(span, format, args); | ||
va_end(args); | ||
|
||
ObjHolder holder; | ||
StringFromUtf8Buffer(buffer.data(), buffer.size() - span.size(), holder.slot()); | ||
ThrowIllegalStateExceptionWithMessage(holder.obj()); | ||
} | ||
#endif | ||
|
||
} // namespace | ||
|
||
|
||
extern "C" { | ||
|
||
// Mostly taken from kotlin-native/runtime/src/mimalloc/c/random.c | ||
void Kotlin_Uuid_getRandomBytes(KRef byteArray, KInt size) { | ||
kotlin::ThreadStateGuard guard(kotlin::ThreadState::kNative); | ||
ArrayHeader* array = byteArray->array(); | ||
uint8_t* address = reinterpret_cast<uint8_t*>(ByteArrayAddressOfElementAt(array, 0)); | ||
|
||
#if KONAN_MACOSX || KONAN_IOS || KONAN_TVOS || KONAN_WATCHOS || KONAN_ANDROID | ||
arc4random_buf(address, size); | ||
#elif KONAN_LINUX | ||
long count = 0; | ||
while (count < size) { | ||
long ret = syscall(SYS_getrandom, address + count, size - count, 0); // blocking | ||
if (ret >= 0) { | ||
count += ret; | ||
} else if (errno != EINTR) { // repeat if interrupted | ||
throwReadingRandomBytesFailed("getrandom returned a negative value: %ld, errno: %d", ret, errno); | ||
} | ||
} | ||
#elif KONAN_WINDOWS | ||
NTSTATUS status = BCryptGenRandom(NULL, (PUCHAR)address, (ULONG)size, BCRYPT_USE_SYSTEM_PREFERRED_RNG); | ||
if (!NT_SUCCESS(status)) { | ||
throwReadingRandomBytesFailed("Unexpected failure in random bytes generation: %ld", status); | ||
} | ||
#else | ||
#error "How to Kotlin_Uuid_getRandomBytes()?" | ||
#endif | ||
} | ||
|
||
} // extern "C" |
18 changes: 18 additions & 0 deletions
18
kotlin-native/runtime/src/main/kotlin/kotlin/uuid/UuidNative.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. | ||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. | ||
*/ | ||
|
||
package kotlin.uuid | ||
|
||
import kotlin.native.internal.GCUnsafeCall | ||
|
||
@GCUnsafeCall("Kotlin_Uuid_getRandomBytes") | ||
private external fun getRandomBytes(byteArray: ByteArray, size: Int): Unit | ||
|
||
@ExperimentalStdlibApi | ||
internal actual fun secureRandomUuid(): Uuid { | ||
val randomBytes = ByteArray(Uuid.SIZE_BYTES) | ||
getRandomBytes(randomBytes, randomBytes.size) | ||
return uuidFromRandomBytes(randomBytes) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
@kotlin.SinceKotlin(version = "2.0") | ||
@kotlin.ExperimentalStdlibApi | ||
public final class Uuid : kotlin.io.Serializable { | ||
public open override operator fun equals(other: kotlin.Any?): kotlin.Boolean | ||
|
||
public open override fun hashCode(): kotlin.Int | ||
|
||
public final fun toByteArray(): kotlin.ByteArray | ||
|
||
public final fun toHexString(): kotlin.String | ||
|
||
@kotlin.internal.InlineOnly | ||
public final inline fun <T> toLongs(action: (mostSignificantBits: kotlin.Long, leastSignificantBits: kotlin.Long) -> T): T | ||
|
||
public open override fun toString(): kotlin.String | ||
|
||
@kotlin.internal.InlineOnly | ||
public final inline fun <T> toULongs(action: (mostSignificantBits: kotlin.ULong, leastSignificantBits: kotlin.ULong) -> T): T | ||
|
||
public companion object of Uuid { | ||
public final val LEXICAL_ORDER: kotlin.Comparator<kotlin.uuid.Uuid> { get; } | ||
|
||
public final val NIL: kotlin.uuid.Uuid { get; } | ||
|
||
public const final val SIZE_BITS: kotlin.Int = 128 { get; } | ||
|
||
public const final val SIZE_BYTES: kotlin.Int = 16 { get; } | ||
|
||
public final fun fromByteArray(byteArray: kotlin.ByteArray): kotlin.uuid.Uuid | ||
|
||
public final fun fromLongs(mostSignificantBits: kotlin.Long, leastSignificantBits: kotlin.Long): kotlin.uuid.Uuid | ||
|
||
public final fun fromULongs(mostSignificantBits: kotlin.ULong, leastSignificantBits: kotlin.ULong): kotlin.uuid.Uuid | ||
|
||
public final fun parse(uuidString: kotlin.String): kotlin.uuid.Uuid | ||
|
||
public final fun parseHex(hexString: kotlin.String): kotlin.uuid.Uuid | ||
|
||
public final fun random(): kotlin.uuid.Uuid | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* | ||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors. | ||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. | ||
*/ | ||
|
||
package kotlin.uuid | ||
|
||
@ExperimentalStdlibApi | ||
internal actual fun secureRandomUuid(): Uuid { | ||
val randomBytes = ByteArray(16) | ||
js("crypto").getRandomValues(randomBytes) | ||
return uuidFromRandomBytes(randomBytes) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.