Tidy native function namespace

This commit is contained in:
tarsin committed 2023-03-22 17:48:10 +08:00
1 parent 8a39bf6ac8
commit 8924d36925
10 files changed
+90 -146

No files matched your search

-35
View File
@@ -1,35 +0,0 @@
/*
* Copyright 2022 Tarsin Norbin
*
* This file is part of EhViewer
*
* EhViewer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* EhViewer is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with EhViewer.
* If not, see <https://www.gnu.org/licenses/>.
*/
package com.hippo
import android.os.ParcelFileDescriptor
import android.system.Int64Ref
import android.system.Os
import java.io.FileDescriptor
private fun sendFileTotally(from: FileDescriptor, to: FileDescriptor) {
Os.sendfile(to, from, Int64Ref(0), Long.MAX_VALUE)
}
infix fun ParcelFileDescriptor.sendTo(fd: FileDescriptor) {
sendFileTotally(fileDescriptor, fd)
}
infix fun ParcelFileDescriptor.sendTo(fd: ParcelFileDescriptor) {
sendFileTotally(fileDescriptor, fd.fileDescriptor)
}
@@ -1,70 +0,0 @@
/*
* Copyright 2022 Tarsin Norbin
*
* This file is part of EhViewer
*
* EhViewer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* EhViewer is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with EhViewer.
* If not, see <https://www.gnu.org/licenses/>.
*/
package com.hippo
import android.content.Context
import android.graphics.ImageDecoder
import android.net.Uri
import android.util.Log
import com.hippo.image.Image
import java.io.FileDescriptor
import java.nio.ByteBuffer
class UriArchiveAccessor(ctx: Context, private val uri: Uri) {
val pfd by lazy { ctx.contentResolver.openFileDescriptor(uri, "r")!! }
fun open(): Int {
Log.d(DEBUG_TAG, "Open archive $uri")
return openArchive(pfd.fd, pfd.statSize)
}
private external fun openArchive(fd: Int, size: Long): Int
private external fun extractToByteBuffer(index: Int): ByteBuffer?
external fun extractToFd(index: Int, fd: Int)
external fun getFilename(index: Int): String
external fun needPassword(): Boolean
external fun providePassword(str: String): Boolean
private external fun closeArchive()
fun close() {
closeArchive()
pfd.close()
Log.d(DEBUG_TAG, "Close archive $uri successfully!")
}
fun getImageSource(index: Int): Image.CloseableSource? {
val buffer = extractToByteBuffer(index)
buffer ?: return null
check(buffer.isDirect)
Image.rewriteGifSource(buffer)
val source = ImageDecoder.createSource(buffer)
return object : Image.CloseableSource {
override val source: ImageDecoder.Source
get() = source
override fun close() {
releaseByteBuffer(buffer)
}
}
}
companion object {
@JvmStatic
private external fun releaseByteBuffer(buffer: ByteBuffer)
}
}
private const val DEBUG_TAG = "UriArchiveAccessor"
+1 -1
View File
@@ -33,7 +33,7 @@ import com.hippo.ehviewer.dao.HistoryInfo
import com.hippo.ehviewer.dao.LocalFavoriteInfo
import com.hippo.ehviewer.dao.QuickSearch
import com.hippo.ehviewer.download.DownloadManager
import com.hippo.sendTo
import com.hippo.util.sendTo
object EhDB {
private const val CUR_DB_VER = 4
@@ -16,10 +16,13 @@
package com.hippo.ehviewer.gallery
import android.content.Context
import android.graphics.ImageDecoder
import android.net.Uri
import com.hippo.UriArchiveAccessor
import android.os.ParcelFileDescriptor
import android.util.Log
import com.hippo.ehviewer.Settings
import com.hippo.image.Image
import com.hippo.image.rewriteGifSource
import com.hippo.unifile.UniFile
import com.hippo.yorozuya.FileUtils
import kotlinx.coroutines.CoroutineScope
@@ -35,26 +38,26 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.sync.withPermit
import java.nio.ByteBuffer
class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow<String>) : PageLoader2(),
CoroutineScope {
class ArchivePageLoader(context: Context, private val uri: Uri, passwdFlow: Flow<String>) : PageLoader2(), CoroutineScope {
override val coroutineContext = Dispatchers.IO + Job()
private val archiveAccessor by lazy { UriArchiveAccessor(context, uri) }
private lateinit var pfd: ParcelFileDescriptor
private val hostJob = launch(start = CoroutineStart.LAZY) {
size = archiveAccessor.open()
Log.d(DEBUG_TAG, "Open archive $uri")
pfd = context.contentResolver.openFileDescriptor(uri, "r")!!
size = openArchive(pfd.fd, pfd.statSize)
if (size == 0) {
return@launch
}
archiveAccessor.run {
if (needPassword()) {
Settings.archivePasswds?.forEach {
if (providePassword(it)) return@launch
}
passwdFlow.collect {
if (providePassword(it)) {
Settings.putPasswdToArchivePasswds(it)
currentCoroutineContext().cancel()
}
if (needPassword()) {
Settings.archivePasswds?.forEach {
if (providePassword(it)) return@launch
}
passwdFlow.collect {
if (providePassword(it)) {
Settings.putPasswdToArchivePasswds(it)
currentCoroutineContext().cancel()
}
}
}
@@ -69,7 +72,9 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow<String>) :
override fun stop() {
cancel()
archiveAccessor.close()
closeArchive()
pfd.close()
Log.d(DEBUG_TAG, "Close archive $uri successfully!")
super.stop()
}
@@ -93,7 +98,19 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow<String>) :
}
private suspend fun doRealWork(index: Int) {
val src = archiveAccessor.getImageSource(index) ?: return
val buffer = extractToByteBuffer(index)
buffer ?: return
check(buffer.isDirect)
rewriteGifSource(buffer)
val source = ImageDecoder.createSource(buffer)
val src = object : Image.CloseableSource {
override val source: ImageDecoder.Source
get() = source
override fun close() {
releaseByteBuffer(buffer)
}
}
runCatching {
currentCoroutineContext().ensureActive()
}.onFailure {
@@ -131,13 +148,13 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow<String>) :
}
override fun getImageFilenameWithExtension(index: Int): String {
return FileUtils.sanitizeFilename(archiveAccessor.getFilename(index))
return FileUtils.sanitizeFilename(getFilename(index))
}
override fun save(index: Int, file: UniFile): Boolean {
runCatching {
file.openFileDescriptor("w").use {
archiveAccessor.extractToFd(index, it.fd)
extractToFd(index, it.fd)
}
}.onFailure {
it.printStackTrace()
@@ -154,4 +171,15 @@ class ArchivePageLoader(context: Context, uri: Uri, passwdFlow: Flow<String>) :
}
override fun preloadPages(pages: List<Int>, pair: Pair<Int, Int>) {}
}
}
private const val DEBUG_TAG = "ArchivePageLoader"
private external fun releaseByteBuffer(buffer: ByteBuffer)
private external fun openArchive(fd: Int, size: Long): Int
private external fun extractToByteBuffer(index: Int): ByteBuffer?
private external fun extractToFd(index: Int, fd: Int)
private external fun getFilename(index: Int): String
private external fun needPassword(): Boolean
private external fun providePassword(str: String): Boolean
private external fun closeArchive()
@@ -28,9 +28,9 @@ import com.hippo.ehviewer.client.referer
import com.hippo.ehviewer.coil.edit
import com.hippo.ehviewer.coil.read
import com.hippo.ehviewer.gallery.SUPPORT_IMAGE_EXTENSIONS
import com.hippo.image.Image
import com.hippo.image.Image.CloseableSource
import com.hippo.sendTo
import com.hippo.image.rewriteGifSource2
import com.hippo.util.sendTo
import com.hippo.unifile.UniFile
import com.hippo.unifile.openOutputStream
import com.hippo.yorozuya.FileUtils
@@ -163,7 +163,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
}
if (contentType == ContentType.Image.GIF)
outFile.openFileDescriptor("rw").use {
Image.rewriteGifSource2(it.fd)
rewriteGifSource2(it.fd)
}
return ret
}
+3 -6
View File
@@ -95,15 +95,12 @@ class Image private constructor(private val src: CloseableSource) {
it.printStackTrace()
}.getOrNull()
}
@JvmStatic
external fun rewriteGifSource(buffer: ByteBuffer)
@JvmStatic
external fun rewriteGifSource2(fd: Int)
}
interface CloseableSource : AutoCloseable {
val source: Source
}
}
external fun rewriteGifSource(buffer: ByteBuffer)
external fun rewriteGifSource2(fd: Int)
@@ -0,0 +1,18 @@
package com.hippo.util
import android.os.ParcelFileDescriptor
import android.system.Int64Ref
import android.system.Os
import java.io.FileDescriptor
private fun sendFileTotally(from: FileDescriptor, to: FileDescriptor) {
Os.sendfile(to, from, Int64Ref(0), Long.MAX_VALUE)
}
infix fun ParcelFileDescriptor.sendTo(fd: FileDescriptor) {
sendFileTotally(fileDescriptor, fd)
}
infix fun ParcelFileDescriptor.sendTo(fd: ParcelFileDescriptor) {
sendFileTotally(fileDescriptor, fd.fileDescriptor)
}
@@ -73,7 +73,7 @@ import com.hippo.ehviewer.gallery.EhPageLoader
import com.hippo.ehviewer.gallery.PageLoader2
import com.hippo.ehviewer.ui.EhActivity
import com.hippo.image.Image
import com.hippo.sendTo
import com.hippo.util.sendTo
import com.hippo.unifile.UniFile
import com.hippo.util.ExceptionUtils
import com.hippo.util.getParcelableCompat