WinApi HANDLE wrapper and functions to auto-throw WinApi error
This commit is contained in:
parent
d9d7e3b9c3
commit
bcb2ba3dee
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
kotlin("multiplatform") version "2.1.10"
|
||||
kotlin("multiplatform") version "2.2.10"
|
||||
}
|
||||
|
||||
group = "ru.landgrafhomyak.utilities"
|
||||
@ -26,7 +26,7 @@ kotlin {
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation("ru.landgrafhomyak.utility:highlevel-try-finally:0.6")
|
||||
implementation("ru.landgrafhomyak.utility:closeable-state-1:1.1")
|
||||
implementation("ru.landgrafhomyak.utility:closeable-state-1:1.2")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1
gradle.properties
Normal file
1
gradle.properties
Normal file
@ -0,0 +1 @@
|
||||
kotlin.mpp.applyDefaultHierarchyTemplate=false
|
||||
@ -1 +1 @@
|
||||
Subproject commit bdb1fe56fa79e50850e8072db0b857955d48b479
|
||||
Subproject commit 4b799c0ecfac0d501ce335147c2ed021e5d4bea9
|
||||
@ -0,0 +1,35 @@
|
||||
package ru.landgrafhomyak.utility.kotlin_native_interop_stdlib_0.windows
|
||||
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlinx.cinterop.ExperimentalForeignApi
|
||||
import platform.windows.CloseHandle
|
||||
import platform.windows.HANDLE
|
||||
import ru.landgrafhomyak.utility.closeable_state_1.CloseableState
|
||||
import ru.landgrafhomyak.utility.closeable_state_1.HandleWrapper
|
||||
import ru.landgrafhomyak.utility.closeable_state_1.ManualStateManipulation
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
public class WindowsHandleWrapper(
|
||||
handle: HANDLE,
|
||||
state: CloseableState,
|
||||
) {
|
||||
private val _orig = HandleWrapper<HANDLE>(handle, state)
|
||||
|
||||
@Suppress("LEAKED_IN_PLACE_LAMBDA", "WRONG_INVOCATION_KIND")
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
public fun <R> useHandle(method: (HANDLE) -> R): R {
|
||||
contract {
|
||||
callsInPlace(method, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
return this._orig.useHandle(method)
|
||||
}
|
||||
|
||||
@ManualStateManipulation
|
||||
public fun close() {
|
||||
this._orig.close()
|
||||
zeroToWinApiErr { CloseHandle(this._orig.handle) }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
@file:OptIn(ExperimentalContracts::class)
|
||||
|
||||
package ru.landgrafhomyak.utility.kotlin_native_interop_stdlib_0.windows
|
||||
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlinx.cinterop.ExperimentalForeignApi
|
||||
import platform.windows.ERROR_SUCCESS
|
||||
import platform.windows.GetLastError
|
||||
import platform.windows.NULL
|
||||
|
||||
private fun _checkErrnoAndThrow(): Nothing {
|
||||
val code = GetLastError()
|
||||
if (code == ERROR_SUCCESS.toUInt())
|
||||
throw RuntimeException("Function returned error status, but no error set")
|
||||
WindowsApiException.throwFromLastWindowsErr()
|
||||
}
|
||||
|
||||
public fun Int.zeroToWinApiErr(): Int {
|
||||
if (this != 0)
|
||||
return this
|
||||
|
||||
_checkErrnoAndThrow()
|
||||
}
|
||||
|
||||
public fun zeroToWinApiErr(call: () -> Int): Int {
|
||||
contract {
|
||||
callsInPlace(call, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
val status = call()
|
||||
if (status != 0)
|
||||
return status
|
||||
|
||||
_checkErrnoAndThrow()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
public fun <R : Any> R?.nullToWinApiErr(): R {
|
||||
if (this != null && this != NULL)
|
||||
return this
|
||||
|
||||
_checkErrnoAndThrow()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalForeignApi::class)
|
||||
public fun <R : Any> nullToWinApiErr(call: () -> R?): R {
|
||||
contract {
|
||||
callsInPlace(call, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
val ref = call()
|
||||
if (ref != null && ref != NULL)
|
||||
return ref
|
||||
|
||||
_checkErrnoAndThrow()
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user