Tidy native function namespace
This commit is contained in:
1 parent
8a39bf6ac8
commit
8924d36925
10 files changed
+90
-146
No files matched your search
@@ -279,7 +279,8 @@ static int archive_get_ctx(archive_ctx **ctxptr, int idx) {
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd, jlong size) {
|
||||
Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_openArchive(JNIEnv *env, jclass thiz, jint fd,
|
||||
jlong size) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
archive_ctx *ctx = NULL;
|
||||
@@ -359,7 +360,8 @@ Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd
|
||||
#pragma ide diagnostic ignored "UnreachableCode"
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_extractToByteBuffer(JNIEnv *env, jobject thiz, jint index) {
|
||||
Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_extractToByteBuffer(JNIEnv *env, jclass thiz,
|
||||
jint index) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
void *addr = MEMPOOL_ADDR_BY_SORTED_IDX(index);
|
||||
@@ -388,7 +390,7 @@ Java_com_hippo_UriArchiveAccessor_extractToByteBuffer(JNIEnv *env, jobject thiz,
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_closeArchive(JNIEnv *env, jobject thiz) {
|
||||
Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_closeArchive(JNIEnv *env, jclass thiz) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
for (int i = 0; i < CTX_POOL_SIZE; i++)
|
||||
@@ -408,14 +410,15 @@ Java_com_hippo_UriArchiveAccessor_closeArchive(JNIEnv *env, jobject thiz) {
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_needPassword(JNIEnv *env, jobject thiz) {
|
||||
Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_needPassword(JNIEnv *env, jclass thiz) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
return need_encrypt;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *env, jobject thiz, jstring str) {
|
||||
Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_providePassword(JNIEnv *env, jclass thiz,
|
||||
jstring str) {
|
||||
EH_UNUSED(thiz);
|
||||
struct archive_entry *entry;
|
||||
archive_ctx *ctx;
|
||||
@@ -445,7 +448,8 @@ Java_com_hippo_UriArchiveAccessor_providePassword(JNIEnv *env, jobject thiz, jst
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_getFilename(JNIEnv *env, jobject thiz, jint index) {
|
||||
Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_getFilename(JNIEnv *env, jclass thiz,
|
||||
jint index) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
index = entries[index].index;
|
||||
@@ -460,7 +464,8 @@ Java_com_hippo_UriArchiveAccessor_getFilename(JNIEnv *env, jobject thiz, jint in
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_extractToFd(JNIEnv *env, jobject thiz, jint index, jint fd) {
|
||||
Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_extractToFd(JNIEnv *env, jclass thiz,
|
||||
jint index, jint fd) {
|
||||
EH_UNUSED(env);
|
||||
EH_UNUSED(thiz);
|
||||
index = entries[index].index;
|
||||
@@ -474,7 +479,8 @@ Java_com_hippo_UriArchiveAccessor_extractToFd(JNIEnv *env, jobject thiz, jint in
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_UriArchiveAccessor_releaseByteBuffer(JNIEnv *env, jobject thiz, jobject buffer) {
|
||||
Java_com_hippo_ehviewer_gallery_ArchivePageLoaderKt_releaseByteBuffer(JNIEnv *env, jclass thiz,
|
||||
jobject buffer) {
|
||||
EH_UNUSED(thiz);
|
||||
void *addr = (*env)->GetDirectBufferAddress(env, buffer);
|
||||
size_t size = (*env)->GetDirectBufferCapacity(env, buffer);
|
||||
|
||||
@@ -43,14 +43,14 @@ static void doRewrite(byte *addr, size_t size) {
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_image_Image_rewriteGifSource(JNIEnv *env, jclass clazz, jobject buffer) {
|
||||
Java_com_hippo_image_ImageKt_rewriteGifSource(JNIEnv *env, jclass clazz, jobject buffer) {
|
||||
byte *addr = (*env)->GetDirectBufferAddress(env, buffer);
|
||||
size_t size = (*env)->GetDirectBufferCapacity(env, buffer);
|
||||
doRewrite(addr, size);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_hippo_image_Image_rewriteGifSource2(JNIEnv *env, jclass clazz, jint fd) {
|
||||
Java_com_hippo_image_ImageKt_rewriteGifSource2(JNIEnv *env, jclass clazz, jint fd) {
|
||||
struct stat64 st;
|
||||
fstat64(fd, &st);
|
||||
size_t size = st.st_size;
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user