You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.7 KiB
52 lines
1.7 KiB
package org.jetbrains.compose.resources |
|
|
|
import kotlinx.browser.window |
|
import kotlinx.coroutines.await |
|
import org.khronos.webgl.ArrayBuffer |
|
import org.khronos.webgl.Int8Array |
|
import org.w3c.fetch.Response |
|
import kotlin.wasm.unsafe.UnsafeWasmMemoryApi |
|
import kotlin.wasm.unsafe.withScopedMemoryAllocator |
|
|
|
/** |
|
* Reads the content of the resource file at the specified path and returns it as a byte array. |
|
* |
|
* @param path The path of the file to read in the resource's directory. |
|
* @return The content of the file as a byte array. |
|
*/ |
|
@OptIn(ExperimentalResourceApi::class) |
|
@InternalResourceApi |
|
actual suspend fun readResourceBytes(path: String): ByteArray { |
|
val resPath = WebResourcesConfiguration.getResourcePath(path) |
|
val response = window.fetch(resPath).await<Response>() |
|
if (!response.ok) { |
|
throw MissingResourceException(resPath) |
|
} |
|
return response.arrayBuffer().await<ArrayBuffer>().toByteArray() |
|
} |
|
|
|
private fun ArrayBuffer.toByteArray(): ByteArray { |
|
val source = Int8Array(this, 0, byteLength) |
|
return jsInt8ArrayToKotlinByteArray(source) |
|
} |
|
|
|
@JsFun( |
|
""" (src, size, dstAddr) => { |
|
const mem8 = new Int8Array(wasmExports.memory.buffer, dstAddr, size); |
|
mem8.set(src); |
|
} |
|
""" |
|
) |
|
internal external fun jsExportInt8ArrayToWasm(src: Int8Array, size: Int, dstAddr: Int) |
|
|
|
internal fun jsInt8ArrayToKotlinByteArray(x: Int8Array): ByteArray { |
|
val size = x.length |
|
|
|
@OptIn(UnsafeWasmMemoryApi::class) |
|
return withScopedMemoryAllocator { allocator -> |
|
val memBuffer = allocator.allocate(size) |
|
val dstAddress = memBuffer.address.toInt() |
|
jsExportInt8ArrayToWasm(x, size, dstAddress) |
|
ByteArray(size) { i -> (memBuffer + i).loadByte() } |
|
} |
|
} |