Browse Source

[resources] Add internal convertPathToUri function

k.tskh/resource-uri
Konstantin Tskhovrebov 2 months ago
parent
commit
1e1969387e
  1. 14
      components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ResourceReader.android.kt
  2. 9
      components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceReader.kt
  3. 14
      components/resources/library/src/desktopMain/kotlin/org/jetbrains/compose/resources/ResourceReader.desktop.kt
  4. 17
      components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt
  5. 5
      components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.js.kt
  6. 30
      components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt
  7. 5
      components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.wasmJs.kt
  8. 19
      components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/ResourceReader.web.kt

14
components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ResourceReader.android.kt

@ -7,7 +7,7 @@ private object AndroidResourceReader
@OptIn(ExperimentalResourceApi::class)
@InternalResourceApi
actual suspend fun readResourceBytes(path: String): ByteArray {
val classLoader = Thread.currentThread().contextClassLoader ?: AndroidResourceReader.javaClass.classLoader
val classLoader = getClassLoader()
val resource = classLoader.getResourceAsStream(path) ?: run {
//try to find a font in the android assets
if (File(path).parentFile?.name.orEmpty() == "font") {
@ -15,4 +15,14 @@ actual suspend fun readResourceBytes(path: String): ByteArray {
} else null
} ?: throw MissingResourceException(path)
return resource.readBytes()
}
}
@OptIn(ExperimentalResourceApi::class)
@InternalResourceApi
actual suspend fun convertPathToUri(path: String): String {
val resource = getClassLoader()?.getResource(path) ?: throw MissingResourceException(path)
return resource.toURI().toString()
}
private fun getClassLoader() =
Thread.currentThread().contextClassLoader ?: AndroidResourceReader.javaClass.classLoader

9
components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceReader.kt

@ -14,6 +14,15 @@ class MissingResourceException(path: String) : Exception("Missing resource with
@InternalResourceApi
expect suspend fun readResourceBytes(path: String): ByteArray
/**
* Converts a given file path to a platform dependent URI string.
*
* @param path The file path to be converted to a URI.
* @return The URI representation of the given file path.
*/
@InternalResourceApi
expect suspend fun convertPathToUri(path: String): String
internal interface ResourceReader {
suspend fun read(path: String): ByteArray
}

14
components/resources/library/src/desktopMain/kotlin/org/jetbrains/compose/resources/ResourceReader.desktop.kt

@ -5,7 +5,17 @@ private object JvmResourceReader
@OptIn(ExperimentalResourceApi::class)
@InternalResourceApi
actual suspend fun readResourceBytes(path: String): ByteArray {
val classLoader = Thread.currentThread().contextClassLoader ?: JvmResourceReader.javaClass.classLoader
val classLoader = getClassLoader()
val resource = classLoader.getResourceAsStream(path) ?: throw MissingResourceException(path)
return resource.readBytes()
}
}
@OptIn(ExperimentalResourceApi::class)
@InternalResourceApi
actual suspend fun convertPathToUri(path: String): String {
val resource = getClassLoader()?.getResource(path) ?: throw MissingResourceException(path)
return resource.toURI().toString()
}
private fun getClassLoader() =
Thread.currentThread().contextClassLoader ?: JvmResourceReader.javaClass.classLoader

17
components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt

@ -2,20 +2,27 @@ package org.jetbrains.compose.resources
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.usePinned
import platform.Foundation.NSBundle
import platform.Foundation.NSFileManager
import platform.Foundation.*
import platform.posix.memcpy
@OptIn(ExperimentalResourceApi::class)
@InternalResourceApi
actual suspend fun readResourceBytes(path: String): ByteArray {
val fileManager = NSFileManager.defaultManager()
// todo: support fallback path at bundle root?
val composeResourcesPath = NSBundle.mainBundle.resourcePath + "/compose-resources/" + path
val contentsAtPath = fileManager.contentsAtPath(composeResourcesPath) ?: throw MissingResourceException(path)
val contentsAtPath = fileManager.contentsAtPath(getFilePathInMainBundle(path)) ?: throw MissingResourceException(path)
return ByteArray(contentsAtPath.length.toInt()).apply {
usePinned {
memcpy(it.addressOf(0), contentsAtPath.bytes, contentsAtPath.length)
}
}
}
@InternalResourceApi
actual suspend fun convertPathToUri(path: String): String {
return NSURL.fileURLWithPath(getFilePathInMainBundle(path)).toString()
}
private fun getFilePathInMainBundle(path: String): String {
// todo: support fallback path at bundle root?
return "${NSBundle.mainBundle.resourcePath}/compose-resources/$path"
}

5
components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.js.kt

@ -17,4 +17,7 @@ actual suspend fun readResourceBytes(path: String): ByteArray {
throw MissingResourceException(resPath)
}
return response.arrayBuffer().await().toByteArray()
}
}
internal actual fun getWindowLocation(): WindowLocation =
window.location.let { WindowLocation(it.origin, it.pathname) }

30
components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt

@ -3,22 +3,36 @@ package org.jetbrains.compose.resources
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.usePinned
import platform.Foundation.NSFileManager
import platform.Foundation.NSURL
import platform.posix.memcpy
@OptIn(ExperimentalResourceApi::class)
@InternalResourceApi
actual suspend fun readResourceBytes(path: String): ByteArray {
val currentDirectoryPath = NSFileManager.defaultManager().currentDirectoryPath
val contentsAtPath = NSFileManager.defaultManager().run {
//todo in future bundle resources with app and use all sourceSets (skikoMain, nativeMain)
contentsAtPath("$currentDirectoryPath/src/macosMain/composeResources/$path")
?: contentsAtPath("$currentDirectoryPath/src/macosTest/composeResources/$path")
?: contentsAtPath("$currentDirectoryPath/src/commonMain/composeResources/$path")
?: contentsAtPath("$currentDirectoryPath/src/commonTest/composeResources/$path")
} ?: throw MissingResourceException(path)
val fm = NSFileManager.defaultManager()
val contentsAtPath = fm.contentsAtPath(getFullFilePath(path)) ?: throw MissingResourceException(path)
return ByteArray(contentsAtPath.length.toInt()).apply {
usePinned {
memcpy(it.addressOf(0), contentsAtPath.bytes, contentsAtPath.length)
}
}
}
@InternalResourceApi
actual suspend fun convertPathToUri(path: String): String {
return NSURL.fileURLWithPath(getFullFilePath(path)).toString()
}
@OptIn(ExperimentalResourceApi::class)
private fun getFullFilePath(path: String): String {
val fm = NSFileManager.defaultManager()
val currentDirectoryPath = fm.currentDirectoryPath
//todo in future bundle resources with app and use all sourceSets (skikoMain, nativeMain)
val filePath = listOf(
"$currentDirectoryPath/src/macosMain/composeResources/$path",
"$currentDirectoryPath/src/macosTest/composeResources/$path",
"$currentDirectoryPath/src/commonMain/composeResources/$path",
"$currentDirectoryPath/src/commonTest/composeResources/$path",
).firstOrNull { fm.fileExistsAtPath(it) } ?: throw MissingResourceException(path)
return filePath
}

5
components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.wasmJs.kt

@ -49,4 +49,7 @@ internal fun jsInt8ArrayToKotlinByteArray(x: Int8Array): ByteArray {
jsExportInt8ArrayToWasm(x, size, dstAddress)
ByteArray(size) { i -> (memBuffer + i).loadByte() }
}
}
}
internal actual fun getWindowLocation(): WindowLocation =
window.location.let { WindowLocation(it.origin, it.pathname) }

19
components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/ResourceReader.web.kt

@ -0,0 +1,19 @@
package org.jetbrains.compose.resources
internal data class WindowLocation(val origin: String, val pathname: String)
internal expect fun getWindowLocation(): WindowLocation
@OptIn(ExperimentalResourceApi::class)
@InternalResourceApi
actual suspend fun convertPathToUri(path: String): String {
val resPath = WebResourcesConfiguration.getResourcePath(path)
return getWindowLocation().let {
if (resPath.startsWith("/")) {
it.origin + resPath
} else if (resPath.startsWith("http://") || resPath.startsWith("https://")) {
resPath
} else {
it.origin + it.pathname + resPath
}
}
}
Loading…
Cancel
Save