1
1
package com.soywiz.korio.file.std
2
2
3
+ import android.content.Context
3
4
import com.soywiz.korio.android.androidContext
4
5
import com.soywiz.klock.*
5
- import com.soywiz.kmem.*
6
- import com.soywiz.korio.async.*
7
6
import com.soywiz.korio.file.*
8
7
import com.soywiz.korio.lang.Closeable
9
8
import com.soywiz.korio.stream.*
10
9
import com.soywiz.korio.util.*
11
10
import kotlinx.coroutines.*
12
- import kotlinx.coroutines.channels.*
13
11
import kotlinx.coroutines.flow.*
14
12
import java.io.*
15
13
import java.io.IOException
@@ -18,7 +16,20 @@ import java.net.*
18
16
private val absoluteCwd by lazy { File (" ." ).absolutePath }
19
17
val tmpdir: String by lazy { System .getProperty(" java.io.tmpdir" ) }
20
18
21
- actual val resourcesVfs: VfsFile by lazy { ResourcesVfsProviderAndroid ()().root.jail() }
19
+ private var androidContext: Context ? = null
20
+ private var resourcesVfsProvider: ResourcesVfsProviderAndroid ? = null
21
+ private lateinit var jailedResourcesVfsFile: VfsFile
22
+
23
+ actual val resourcesVfs: VfsFile
24
+ get() {
25
+ if (resourcesVfsProvider == null ) {
26
+ resourcesVfsProvider = ResourcesVfsProviderAndroid ().apply {
27
+ jailedResourcesVfsFile = this .invoke().root.jail()
28
+ }
29
+ }
30
+ return jailedResourcesVfsFile
31
+ }
32
+
22
33
actual val rootLocalVfs: VfsFile by lazy { localVfs(absoluteCwd) }
23
34
actual val applicationVfs: VfsFile by lazy { localVfs(absoluteCwd) }
24
35
actual val applicationDataVfs: VfsFile by lazy { localVfs(absoluteCwd) }
@@ -38,38 +49,57 @@ suspend fun File.open(mode: VfsOpenMode) = localVfs(this).open(mode)
38
49
fun File.toVfs () = localVfs(this )
39
50
fun UrlVfs (url : URL ): VfsFile = UrlVfs (url.toString())
40
51
41
- private class ResourcesVfsProviderAndroid {
52
+ class ResourcesVfsProviderAndroid {
53
+
54
+ private var androidResourcesVfs: AndroidResourcesVfs ? = null
55
+
56
+ fun deinit () {
57
+ androidContext = null
58
+ androidResourcesVfs?.context = null
59
+ androidResourcesVfs = null
60
+ }
61
+
42
62
operator fun invoke (): Vfs {
43
- val merged = MergedVfs ()
44
63
45
- return object : Vfs .Decorator (merged.root) {
46
- override suspend fun init () = run { merged + = AndroidResourcesVfs (androidContext()).root }
64
+ val merged = MergedVfs ()
65
+
66
+ return object : Vfs .Decorator (merged.root) {
67
+ override suspend fun init () = run<ResourcesVfsProviderAndroid , Unit > {
68
+ androidContext = androidContext()
69
+ androidResourcesVfs = AndroidResourcesVfs (androidContext).apply {
70
+ merged + = root
71
+ }
72
+ }
47
73
override fun toString (): String = " ResourcesVfs"
48
74
}
49
75
}
50
76
}
51
77
52
- class AndroidResourcesVfs (val context : android.content.Context ) : Vfs() {
78
+ class AndroidResourcesVfs (var context : Context ? ) : Vfs() {
79
+
53
80
override suspend fun open (path : String , mode : VfsOpenMode ): AsyncStream {
54
81
return readRange(path, LONG_ZERO_TO_MAX_RANGE ).openAsync(mode.cmode)
55
82
}
56
83
57
84
override suspend fun readRange (path : String , range : LongRange ): ByteArray = executeIo {
58
- // val path = "/assets/" + path.trim('/')
59
- val rpath = path.trim(' /' )
60
-
61
- val fs = context.assets.open(rpath)
62
- fs.skip(range.start)
63
- val out = ByteArrayOutputStream ()
64
- val temp = ByteArray (16 * 1024 )
65
- var available = (range.endExclusiveClamped - range.start)
66
- while (available >= 0 ) {
67
- val read = fs.read(temp, 0 , Math .min(temp.size.toLong(), available).toInt())
68
- if (read <= 0 ) break
69
- out .write(temp, 0 , read)
70
- available - = read
71
- }
72
- out .toByteArray()
85
+ context?.let { context ->
86
+
87
+ // val path = "/assets/" + path.trim('/')
88
+ val rpath = path.trim(' /' )
89
+
90
+ val fs = context.assets.open(rpath)
91
+ fs.skip(range.start)
92
+ val out = ByteArrayOutputStream ()
93
+ val temp = ByteArray (16 * 1024 )
94
+ var available = (range.endExclusiveClamped - range.start)
95
+ while (available >= 0 ) {
96
+ val read = fs.read(temp, 0 , Math .min(temp.size.toLong(), available).toInt())
97
+ if (read <= 0 ) break
98
+ out .write(temp, 0 , read)
99
+ available - = read
100
+ }
101
+ out .toByteArray()
102
+ } ? : throw IllegalStateException (" Android context not set and required to access assets" )
73
103
}
74
104
}
75
105
@@ -257,3 +287,9 @@ private class LocalVfsJvm : LocalVfsV2() {
257
287
258
288
override fun toString (): String = " LocalVfs"
259
289
}
290
+
291
+ actual fun cleanUpResourcesVfs () {
292
+ androidContext = null
293
+ resourcesVfsProvider?.deinit()
294
+ resourcesVfsProvider = null
295
+ }
0 commit comments