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

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() }
}
}