blob: f8abae445fd3007808e8f14312df2adbccf9df26 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.utils
import android.net.Uri
import androidx.documentfile.provider.DocumentFile
import org.yuzu.yuzu_emu.YuzuApplication
import org.yuzu.yuzu_emu.model.MinimalDocumentFile
import java.io.File
import java.util.*
class DocumentsTree {
private var root: DocumentsNode? = null
fun setRoot(rootUri: Uri?) {
root = null
root = DocumentsNode()
root!!.uri = rootUri
root!!.isDirectory = true
}
fun openContentUri(filepath: String, openMode: String?): Int {
val node = resolvePath(filepath) ?: return -1
return FileUtil.openContentUri(YuzuApplication.appContext, node.uri.toString(), openMode)
}
fun getFileSize(filepath: String): Long {
val node = resolvePath(filepath)
return if (node == null || node.isDirectory) {
0
} else FileUtil.getFileSize(YuzuApplication.appContext, node.uri.toString())
}
fun exists(filepath: String): Boolean {
return resolvePath(filepath) != null
}
fun isDirectory(filepath: String): Boolean {
val node = resolvePath(filepath)
return node != null && node.isDirectory
}
private fun resolvePath(filepath: String): DocumentsNode? {
val tokens = StringTokenizer(filepath, File.separator, false)
var iterator = root
while (tokens.hasMoreTokens()) {
val token = tokens.nextToken()
if (token.isEmpty()) continue
iterator = find(iterator, token)
if (iterator == null) return null
}
return iterator
}
private fun find(parent: DocumentsNode?, filename: String): DocumentsNode? {
if (parent!!.isDirectory && !parent.loaded) {
structTree(parent)
}
return parent.children[filename]
}
/**
* Construct current level directory tree
* @param parent parent node of this level
*/
private fun structTree(parent: DocumentsNode) {
val documents = FileUtil.listFiles(YuzuApplication.appContext, parent.uri!!)
for (document in documents) {
val node = DocumentsNode(document)
node.parent = parent
parent.children[node.name] = node
}
parent.loaded = true
}
private class DocumentsNode {
var parent: DocumentsNode? = null
val children: MutableMap<String?, DocumentsNode> = HashMap()
var name: String? = null
var uri: Uri? = null
var loaded = false
var isDirectory = false
constructor()
constructor(document: MinimalDocumentFile) {
name = document.filename
uri = document.uri
isDirectory = document.isDirectory
loaded = !isDirectory
}
private constructor(document: DocumentFile, isCreateDir: Boolean) {
name = document.name
uri = document.uri
isDirectory = isCreateDir
loaded = true
}
private fun rename(name: String) {
if (parent == null) {
return
}
parent!!.children.remove(this.name)
this.name = name
parent!!.children[name] = this
}
}
companion object {
fun isNativePath(path: String): Boolean {
return if (path.isNotEmpty()) {
path[0] == '/'
} else false
}
}
}
|