diff options
Diffstat (limited to 'libs/samba/src/main/java/org')
5 files changed, 239 insertions, 0 deletions
diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt new file mode 100644 index 0000000..360aaa9 --- /dev/null +++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt @@ -0,0 +1,92 @@ +// Using RegisterNatives +@file:Suppress("KotlinJniMissingFunction") + +package org.the_jk.cleversync.io.samba + +import androidx.annotation.Keep + +@Keep +internal object NativeSamba { + fun newContext(): Context = NativeContext(nativeContextNew()) + + interface Object { + fun destroy() + } + + interface Context : Object { + fun parseUrl(url: String): Url? + fun connect(url: Url): Boolean + fun lastError(): String + fun openDir(path: String): Dir? + } + + interface Url : Object { + fun path(): String + } + + interface Dir : Object { + val path: String + } + + private class NativeContext(private var ptr: Long): Context { + override fun destroy() { + if (ptr == 0L) return + nativeContextDestroy(ptr) + ptr = 0L + } + + override fun parseUrl(url: String): Url? { + val ptr = nativeContextParseUrl(ptr, url) + return if (ptr != 0L) NativeUrl(ptr) else null + } + + override fun connect(url: Url): Boolean { + return nativeContextConnect(ptr, (url as NativeUrl).get()) + } + + override fun lastError(): String { + return nativeContextGetError(ptr) + } + + override fun openDir(path: String): Dir? { + val dir = nativeContextOpenDir(ptr, path) + return if (dir != 0L) NativeDir(path, dir) else null + } + } + + private class NativeUrl(private var ptr: Long): Url { + override fun destroy() { + if (ptr == 0L) return + nativeUrlDestroy(ptr) + ptr = 0L + } + + override fun path(): String = nativeUrlPath(ptr) + + fun get(): Long = ptr + } + + private class NativeDir(override val path: String, private var ptr: Long): Dir { + override fun destroy() { + if (ptr == 0L) return + nativeDirDestroy(ptr) + ptr = 0L + } + } + + init { + System.loadLibrary("samba") + } + + private external fun nativeContextNew(): Long + private external fun nativeContextDestroy(ptr: Long) + private external fun nativeContextParseUrl(ptr: Long, url: String): Long + private external fun nativeContextConnect(ptr: Long, url: Long): Boolean + private external fun nativeContextGetError(ptr: Long): String + private external fun nativeContextOpenDir(ptr: Long, path: String): Long + + private external fun nativeUrlDestroy(ptr: Long) + private external fun nativeUrlPath(ptr: Long): String + + private external fun nativeDirDestroy(ptr: Long) +} diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt new file mode 100644 index 0000000..03d3a9e --- /dev/null +++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt @@ -0,0 +1,32 @@ +package org.the_jk.cleversync.io.samba + +internal class SambaConnection(uri: String) { + private val context = NativeSamba.newContext() + private val url = context.parseUrl(uri) + + val connected = if (url != null) { context.connect(url) } else false + + val error: String + get() = context.lastError() + + fun openDir(path: String): NativeSamba.Dir? = + if (connected) context.openDir(join(url!!.path(), path)) else null + + companion object { + fun join(a: String, b: String): String { + if (a.isEmpty() || b.startsWith("/")) return b + if (b.isEmpty()) return a + return if (a.endsWith("/")) a + b else "${a}/${b}" + } + + fun dirname(path: String): String { + val last = path.lastIndexOf('/') + return if (last == -1) path else path.substring(last + 1) + } + + fun basename(path: String): String { + val last = path.lastIndexOf('/') + return if (last < 1) "" else path.substring(0, last - 1) + } + } +} diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaDirectory.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaDirectory.kt new file mode 100644 index 0000000..b82e745 --- /dev/null +++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaDirectory.kt @@ -0,0 +1,88 @@ +package org.the_jk.cleversync.io.samba + +import androidx.lifecycle.LiveData +import org.the_jk.cleversync.io.Directory +import org.the_jk.cleversync.io.File +import org.the_jk.cleversync.io.Link +import org.the_jk.cleversync.io.ModifiableDirectory +import org.the_jk.cleversync.io.ModifiableFile +import org.the_jk.cleversync.io.ModifiableLink + +internal open class SambaDirectory( + private val conn: SambaConnection, + private val dir: NativeSamba.Dir, +) : ModifiableDirectory { + override fun modifiableOpenDir(name: String): ModifiableDirectory? { + val dir = conn.openDir(SambaConnection.join(dir.path, name)) ?: return null + return SambaDirectory(conn, dir) + } + + override fun modifiableOpenFile(name: String): ModifiableFile? { + TODO("Not yet implemented") + } + + override fun modifiableOpenLink(name: String): ModifiableLink? { + TODO("Not yet implemented") + } + + override fun modifiableList(): ModifiableDirectory.Content { + TODO("Not yet implemented") + } + + override fun modifiableLiveList(): LiveData<ModifiableDirectory.Content> { + TODO("Not yet implemented") + } + + override fun createDirectory(name: String): ModifiableDirectory { + TODO("Not yet implemented") + } + + override fun createFile(name: String): ModifiableFile { + TODO("Not yet implemented") + } + + override fun createLink(name: String, target: Directory): ModifiableLink { + TODO("Not yet implemented") + } + + override fun createLink(name: String, target: File): ModifiableLink { + TODO("Not yet implemented") + } + + override fun createLink(name: String, target: String): ModifiableLink { + TODO("Not yet implemented") + } + + override fun removeDirectory(name: String): Boolean { + TODO("Not yet implemented") + } + + override fun removeFile(name: String): Boolean { + TODO("Not yet implemented") + } + + override fun removeLink(name: String): Boolean { + TODO("Not yet implemented") + } + + override val name: String + get() = SambaConnection.dirname(dir.path) + + override fun openDir(name: String) = modifiableOpenDir(name) + + override fun openFile(name: String): File? { + TODO("Not yet implemented") + } + + override fun openLink(name: String): Link? { + TODO("Not yet implemented") + } + + override fun list(): Directory.Content { + TODO("Not yet implemented") + } + + override fun liveList(): LiveData<Directory.Content> { + TODO("Not yet implemented") + } +} diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaTree.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaTree.kt new file mode 100644 index 0000000..8b4a86d --- /dev/null +++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaTree.kt @@ -0,0 +1,10 @@ +package org.the_jk.cleversync.io.samba + +import android.content.res.Resources +import org.the_jk.cleversync.io.ModifiableTree + +internal class SambaTree(conn: SambaConnection, root: NativeSamba.Dir) : SambaDirectory(conn, root), ModifiableTree { + override fun description(resources: Resources): CharSequence { + TODO("Not yet implemented") + } +} diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt b/libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt new file mode 100644 index 0000000..3455de8 --- /dev/null +++ b/libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt @@ -0,0 +1,17 @@ +package org.the_jk.cleversync.samba + +import org.the_jk.cleversync.io.ModifiableTree +import org.the_jk.cleversync.io.Tree +import org.the_jk.cleversync.io.samba.SambaConnection +import org.the_jk.cleversync.io.samba.SambaTree + +object SambaTreeFactory { + fun tree(uri: String): Result<Tree> = modifiableTree(uri) + + fun modifiableTree(uri: String): Result<ModifiableTree> { + val connection = SambaConnection(uri) + if (!connection.connected) return Result.failure(Exception(connection.error)) + val root = connection.openDir("") ?: return Result.failure(Exception(connection.error)) + return Result.success(SambaTree(connection, root)) + } +} |
