Convert SpiderDen to kotlin
This commit is contained in:
1 parent
014b8db20d
commit
0834ff26be
2 files changed
+311
-373
No files matched your search
@@ -33,7 +33,6 @@ import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.ProcessLifecycleOwner
|
||||
import coil.ImageLoader
|
||||
import coil.ImageLoaderFactory
|
||||
import coil.disk.DiskCache
|
||||
import com.hippo.Native
|
||||
import com.hippo.app.BaseDialogBuilder
|
||||
import com.hippo.ehviewer.client.EhCookieStore
|
||||
@@ -47,7 +46,6 @@ import com.hippo.ehviewer.client.data.GalleryDetail
|
||||
import com.hippo.ehviewer.client.parser.EventPaneParser
|
||||
import com.hippo.ehviewer.dao.buildMainDB
|
||||
import com.hippo.ehviewer.download.DownloadManager
|
||||
import com.hippo.ehviewer.spider.SpiderDen
|
||||
import com.hippo.ehviewer.ui.CommonOperations
|
||||
import com.hippo.ehviewer.ui.EhActivity
|
||||
import com.hippo.util.BitmapUtils
|
||||
@@ -107,7 +105,6 @@ class EhApplication : Application(), DefaultLifecycleObserver, ImageLoaderFactor
|
||||
Settings.initialize()
|
||||
ReadableTime.initialize(this)
|
||||
AppConfig.initialize(this)
|
||||
SpiderDen.initialize(this)
|
||||
BitmapUtils.initialize(this)
|
||||
EhTagDatabase.update()
|
||||
AppCompatDelegate.setDefaultNightMode(Settings.getTheme())
|
||||
|
||||
@@ -13,471 +13,412 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:OptIn(ExperimentalCoilApi::class)
|
||||
|
||||
package com.hippo.ehviewer.spider;
|
||||
package com.hippo.ehviewer.spider
|
||||
|
||||
import android.content.Context;
|
||||
import coil.annotation.ExperimentalCoilApi
|
||||
import coil.disk.DiskCache
|
||||
import com.hippo.Native.mapFd
|
||||
import com.hippo.Native.unmapDirectByteBuffer
|
||||
import com.hippo.ehviewer.EhApplication.Companion.application
|
||||
import com.hippo.ehviewer.EhDB
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.client.EhCacheKeyFactory
|
||||
import com.hippo.ehviewer.client.EhUtils.getSuitableTitle
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo
|
||||
import com.hippo.ehviewer.gallery.PageLoader2
|
||||
import com.hippo.image.Image.ByteBufferSource
|
||||
import com.hippo.io.UniFileInputStreamPipe
|
||||
import com.hippo.io.UniFileOutputStreamPipe
|
||||
import com.hippo.streampipe.InputStreamPipe
|
||||
import com.hippo.streampipe.OutputStreamPipe
|
||||
import com.hippo.unifile.RawFile
|
||||
import com.hippo.unifile.UniFile
|
||||
import com.hippo.yorozuya.FileUtils
|
||||
import com.hippo.yorozuya.IOUtils
|
||||
import com.hippo.yorozuya.MathUtils
|
||||
import com.hippo.yorozuya.Utilities
|
||||
import okio.buffer
|
||||
import okio.sink
|
||||
import okio.source
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.io.RandomAccessFile
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.channels.FileChannel
|
||||
import java.util.Locale
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
class SpiderDen(private val mGalleryInfo: GalleryInfo) {
|
||||
private val mGid: Long = mGalleryInfo.gid
|
||||
private var mDownloadDir: UniFile? = getGalleryDownloadDir(mGid)
|
||||
|
||||
import com.hippo.Native;
|
||||
import com.hippo.ehviewer.EhApplication;
|
||||
import com.hippo.ehviewer.EhDB;
|
||||
import com.hippo.ehviewer.Settings;
|
||||
import com.hippo.ehviewer.client.EhCacheKeyFactory;
|
||||
import com.hippo.ehviewer.client.EhUtils;
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo;
|
||||
import com.hippo.ehviewer.gallery.PageLoader2;
|
||||
import com.hippo.image.Image;
|
||||
import com.hippo.io.UniFileInputStreamPipe;
|
||||
import com.hippo.io.UniFileOutputStreamPipe;
|
||||
import com.hippo.streampipe.InputStreamPipe;
|
||||
import com.hippo.streampipe.OutputStreamPipe;
|
||||
import com.hippo.unifile.RawFile;
|
||||
import com.hippo.unifile.UniFile;
|
||||
import com.hippo.yorozuya.FileUtils;
|
||||
import com.hippo.yorozuya.IOUtils;
|
||||
import com.hippo.yorozuya.MathUtils;
|
||||
import com.hippo.yorozuya.Utilities;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.Locale;
|
||||
|
||||
import coil.disk.DiskCache;
|
||||
import okio.BufferedSource;
|
||||
import okio.Okio;
|
||||
|
||||
public final class SpiderDen {
|
||||
|
||||
@Nullable
|
||||
private static DiskCache sCache; // We use data to store image file, and metadata for image type
|
||||
private final GalleryInfo mGalleryInfo;
|
||||
private final long mGid;
|
||||
@Nullable
|
||||
private UniFile mDownloadDir;
|
||||
private volatile int mMode = SpiderQueen.MODE_READ;
|
||||
|
||||
public SpiderDen(GalleryInfo galleryInfo) {
|
||||
mGalleryInfo = galleryInfo;
|
||||
mGid = galleryInfo.getGid();
|
||||
mDownloadDir = getGalleryDownloadDir(galleryInfo.getGid());
|
||||
}
|
||||
|
||||
public static void initialize(Context context) {
|
||||
sCache = new DiskCache.Builder().directory(new File(context.getCacheDir(), "gallery_image"))
|
||||
.maxSizeBytes((long) MathUtils.clamp(Settings.getReadCacheSize(), 40, 1280) * 1024 * 1024).build();
|
||||
}
|
||||
|
||||
public static UniFile getGalleryDownloadDir(long gid) {
|
||||
UniFile dir = Settings.getDownloadLocation();
|
||||
// Read from DB
|
||||
String dirname = EhDB.getDownloadDirname(gid);
|
||||
if (dir != null && dirname != null) {
|
||||
// Some dirname may be invalid in some version
|
||||
dirname = FileUtils.sanitizeFilename(dirname);
|
||||
EhDB.putDownloadDirname(gid, dirname);
|
||||
return dir.subFile(dirname);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extension with dot
|
||||
*/
|
||||
public static String generateImageFilename(int index, String extension) {
|
||||
return String.format(Locale.US, "%08d%s", index + 1, extension);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static UniFile findImageFile(UniFile dir, int index) {
|
||||
for (String extension : PageLoader2.SUPPORT_IMAGE_EXTENSIONS) {
|
||||
String filename = generateImageFilename(index, extension);
|
||||
UniFile file = dir.findFile(filename);
|
||||
if (file != null) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setMode(@SpiderQueen.Mode int mode) {
|
||||
mMode = mode;
|
||||
@Volatile
|
||||
private var mMode = SpiderQueen.MODE_READ
|
||||
|
||||
fun setMode(@SpiderQueen.Mode mode: Int) {
|
||||
mMode = mode
|
||||
if (mode == SpiderQueen.MODE_DOWNLOAD) {
|
||||
ensureDownloadDir();
|
||||
ensureDownloadDir()
|
||||
}
|
||||
}
|
||||
|
||||
private boolean ensureDownloadDir() {
|
||||
private fun ensureDownloadDir(): Boolean {
|
||||
if (mDownloadDir == null) {
|
||||
var dirname = FileUtils.sanitizeFilename(mGid + "-" + EhUtils.getSuitableTitle(mGalleryInfo));
|
||||
EhDB.putDownloadDirname(mGid, dirname);
|
||||
mDownloadDir = getGalleryDownloadDir(mGid);
|
||||
val dirname =
|
||||
FileUtils.sanitizeFilename(mGid.toString() + "-" + getSuitableTitle(mGalleryInfo))
|
||||
EhDB.putDownloadDirname(mGid, dirname)
|
||||
mDownloadDir = getGalleryDownloadDir(mGid)
|
||||
}
|
||||
return mDownloadDir != null && mDownloadDir.ensureDir();
|
||||
return mDownloadDir != null && mDownloadDir!!.ensureDir()
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return switch (mMode) {
|
||||
case SpiderQueen.MODE_READ -> sCache != null;
|
||||
case SpiderQueen.MODE_DOWNLOAD -> mDownloadDir != null && mDownloadDir.isDirectory();
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public UniFile getDownloadDir() {
|
||||
if (mDownloadDir == null) {
|
||||
mDownloadDir = getGalleryDownloadDir(mGid);
|
||||
val isReady: Boolean
|
||||
get() = when (mMode) {
|
||||
SpiderQueen.MODE_READ -> true
|
||||
SpiderQueen.MODE_DOWNLOAD -> mDownloadDir != null && mDownloadDir!!.isDirectory
|
||||
else -> false
|
||||
}
|
||||
return mDownloadDir != null && mDownloadDir.isDirectory() ? mDownloadDir : null;
|
||||
}
|
||||
|
||||
private boolean containInCache(int index) {
|
||||
if (sCache == null) {
|
||||
return false;
|
||||
val downloadDir: UniFile?
|
||||
get() {
|
||||
if (mDownloadDir == null) {
|
||||
mDownloadDir = getGalleryDownloadDir(mGid)
|
||||
}
|
||||
return if (mDownloadDir != null && mDownloadDir!!.isDirectory) mDownloadDir else null
|
||||
}
|
||||
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
var snapshot = sCache.get(key);
|
||||
var exist = snapshot != null;
|
||||
if (exist) snapshot.close();
|
||||
return exist;
|
||||
private fun containInCache(index: Int): Boolean {
|
||||
val key = EhCacheKeyFactory.getImageKey(mGid, index)
|
||||
return sCache[key]?.apply { close() } != null
|
||||
}
|
||||
|
||||
private boolean containInDownloadDir(int index) {
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find image file in download dir
|
||||
return findImageFile(dir, index) != null;
|
||||
private fun containInDownloadDir(index: Int): Boolean {
|
||||
val dir = downloadDir ?: return false
|
||||
return findImageFile(dir, index) != null
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extension with dot
|
||||
*/
|
||||
private String fixExtension(String extension) {
|
||||
if (Utilities.contain(PageLoader2.SUPPORT_IMAGE_EXTENSIONS, extension)) {
|
||||
return extension;
|
||||
private fun fixExtension(extension: String): String {
|
||||
return if (Utilities.contain(
|
||||
PageLoader2.SUPPORT_IMAGE_EXTENSIONS,
|
||||
extension
|
||||
)
|
||||
) {
|
||||
extension
|
||||
} else {
|
||||
return PageLoader2.SUPPORT_IMAGE_EXTENSIONS[0];
|
||||
PageLoader2.SUPPORT_IMAGE_EXTENSIONS[0]
|
||||
}
|
||||
}
|
||||
|
||||
private boolean copyFromCacheToDownloadDir(int index) {
|
||||
if (sCache == null) {
|
||||
return false;
|
||||
}
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return false;
|
||||
}
|
||||
private fun copyFromCacheToDownloadDir(index: Int): Boolean {
|
||||
val dir = downloadDir ?: return false
|
||||
// Find image file in cache
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
var snapshot = sCache.get(key);
|
||||
if (snapshot == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OutputStream os = null;
|
||||
try (snapshot; FileInputStream is = new FileInputStream(snapshot.getData().toFile()); BufferedSource buf = Okio.buffer(Okio.source(snapshot.getMetadata().toFile()))) {
|
||||
// Get extension
|
||||
String extension = fixExtension("." + buf.readUtf8Line());
|
||||
// Copy from cache to download dir
|
||||
UniFile file = dir.createFile(generateImageFilename(index, extension));
|
||||
if (file == null) {
|
||||
return false;
|
||||
val key = EhCacheKeyFactory.getImageKey(mGid, index)
|
||||
val snapshot = sCache[key] ?: return false
|
||||
var os: OutputStream? = null
|
||||
try {
|
||||
snapshot.use {
|
||||
FileInputStream(snapshot.data.toFile()).use { `is` ->
|
||||
snapshot.metadata.toFile().source().buffer().use { buf ->
|
||||
// Get extension
|
||||
val extension = fixExtension("." + buf.readUtf8Line())
|
||||
// Copy from cache to download dir
|
||||
val file = dir.createFile(generateImageFilename(index, extension))
|
||||
?: return false
|
||||
os = file.openOutputStream()
|
||||
IOUtils.copy(`is`, os)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
os = file.openOutputStream();
|
||||
IOUtils.copy(is, os);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
} catch (e: IOException) {
|
||||
return false
|
||||
} finally {
|
||||
IOUtils.closeQuietly(os);
|
||||
IOUtils.closeQuietly(os)
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contain(int index) {
|
||||
if (mMode == SpiderQueen.MODE_READ) {
|
||||
return containInCache(index) || containInDownloadDir(index);
|
||||
} else if (mMode == SpiderQueen.MODE_DOWNLOAD) {
|
||||
return containInDownloadDir(index) || copyFromCacheToDownloadDir(index);
|
||||
} else {
|
||||
return false;
|
||||
fun contain(index: Int): Boolean {
|
||||
return when (mMode) {
|
||||
SpiderQueen.MODE_READ -> {
|
||||
containInCache(index) || containInDownloadDir(index)
|
||||
}
|
||||
|
||||
SpiderQueen.MODE_DOWNLOAD -> {
|
||||
containInDownloadDir(index) || copyFromCacheToDownloadDir(index)
|
||||
}
|
||||
|
||||
else -> {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean removeFromCache(int index) {
|
||||
if (sCache == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
return sCache.remove(key);
|
||||
private fun removeFromCache(index: Int): Boolean {
|
||||
val key = EhCacheKeyFactory.getImageKey(mGid, index)
|
||||
return sCache.remove(key)
|
||||
}
|
||||
|
||||
private boolean removeFromDownloadDir(int index) {
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result = false;
|
||||
for (int i = 0, n = PageLoader2.SUPPORT_IMAGE_EXTENSIONS.length; i < n; i++) {
|
||||
String filename = generateImageFilename(index, PageLoader2.SUPPORT_IMAGE_EXTENSIONS[i]);
|
||||
UniFile file = dir.subFile(filename);
|
||||
private fun removeFromDownloadDir(index: Int): Boolean {
|
||||
val dir = downloadDir ?: return false
|
||||
var result = false
|
||||
var i = 0
|
||||
val n = PageLoader2.SUPPORT_IMAGE_EXTENSIONS.size
|
||||
while (i < n) {
|
||||
val filename = generateImageFilename(index, PageLoader2.SUPPORT_IMAGE_EXTENSIONS[i])
|
||||
val file = dir.subFile(filename)
|
||||
if (file != null) {
|
||||
result |= file.delete();
|
||||
result = result or file.delete()
|
||||
}
|
||||
i++
|
||||
}
|
||||
return result;
|
||||
return result
|
||||
}
|
||||
|
||||
public boolean remove(int index) {
|
||||
boolean result = removeFromCache(index);
|
||||
result |= removeFromDownloadDir(index);
|
||||
return result;
|
||||
fun remove(index: Int): Boolean {
|
||||
var result = removeFromCache(index)
|
||||
result = result or removeFromDownloadDir(index)
|
||||
return result
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private OutputStreamPipe openCacheOutputStreamPipe(int index, @Nullable String extension) {
|
||||
if (sCache == null) {
|
||||
return null;
|
||||
private fun openCacheOutputStreamPipe(index: Int, extension: String): OutputStreamPipe? {
|
||||
val key = EhCacheKeyFactory.getImageKey(mGid, index)
|
||||
val editor = sCache.edit(key) ?: return null
|
||||
try {
|
||||
editor.metadata.toFile().sink().buffer().use { sink -> sink.writeUtf8(extension) }
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return object : OutputStreamPipe {
|
||||
private var os: OutputStream? = null
|
||||
override fun release() {
|
||||
editor.commit()
|
||||
}
|
||||
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
var editor = sCache.edit(key);
|
||||
if (editor == null) return null;
|
||||
try (var sink = Okio.buffer(Okio.sink(editor.getMetadata().toFile()))) {
|
||||
sink.writeUtf8(extension);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@Throws(IOException::class)
|
||||
override fun open(): OutputStream {
|
||||
if (os != null) IOUtils.closeQuietly(os)
|
||||
os = FileOutputStream(editor.data.toFile())
|
||||
return os!!
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
if (os != null) IOUtils.closeQuietly(os)
|
||||
}
|
||||
}
|
||||
return new OutputStreamPipe() {
|
||||
private OutputStream os = null;
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OutputStream open() throws IOException {
|
||||
if (os != null) IOUtils.closeQuietly(os);
|
||||
os = new FileOutputStream(editor.getData().toFile());
|
||||
return os;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (os != null) IOUtils.closeQuietly(os);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extension without dot
|
||||
*/
|
||||
@Nullable
|
||||
private OutputStreamPipe openDownloadOutputStreamPipe(int index, @Nullable String extension) {
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return null;
|
||||
}
|
||||
private fun openDownloadOutputStreamPipe(index: Int, extension: String): OutputStreamPipe? {
|
||||
var extension = extension
|
||||
val dir = downloadDir ?: return null
|
||||
extension = fixExtension(".$extension")
|
||||
val file = dir.createFile(generateImageFilename(index, extension))
|
||||
return file?.let { UniFileOutputStreamPipe(it) }
|
||||
}
|
||||
|
||||
extension = fixExtension('.' + extension);
|
||||
UniFile file = dir.createFile(generateImageFilename(index, extension));
|
||||
if (file != null) {
|
||||
return new UniFileOutputStreamPipe(file);
|
||||
} else {
|
||||
return null;
|
||||
fun openOutputStreamPipe(index: Int, extension: String): OutputStreamPipe? {
|
||||
return when (mMode) {
|
||||
SpiderQueen.MODE_READ -> {
|
||||
// Return the download pipe is the gallery has been downloaded
|
||||
var pipe = openDownloadOutputStreamPipe(index, extension)
|
||||
if (pipe == null) {
|
||||
pipe = openCacheOutputStreamPipe(index, extension)
|
||||
}
|
||||
pipe
|
||||
}
|
||||
|
||||
SpiderQueen.MODE_DOWNLOAD -> {
|
||||
openDownloadOutputStreamPipe(index, extension)
|
||||
}
|
||||
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OutputStreamPipe openOutputStreamPipe(int index, @Nullable String extension) {
|
||||
if (mMode == SpiderQueen.MODE_READ) {
|
||||
// Return the download pipe is the gallery has been downloaded
|
||||
OutputStreamPipe pipe = openDownloadOutputStreamPipe(index, extension);
|
||||
if (pipe == null) {
|
||||
pipe = openCacheOutputStreamPipe(index, extension);
|
||||
private fun openCacheInputStreamPipe(index: Int): InputStreamPipe? {
|
||||
val key = EhCacheKeyFactory.getImageKey(mGid, index)
|
||||
val snapshot = sCache[key] ?: return null
|
||||
return object : InputStreamPipe {
|
||||
private var `is`: InputStream? = null
|
||||
override fun release() {
|
||||
snapshot.close()
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun open(): InputStream {
|
||||
if (`is` != null) IOUtils.closeQuietly(`is`)
|
||||
`is` = FileInputStream(snapshot.data.toFile())
|
||||
return `is`!!
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
if (`is` != null) IOUtils.closeQuietly(`is`)
|
||||
}
|
||||
return pipe;
|
||||
} else if (mMode == SpiderQueen.MODE_DOWNLOAD) {
|
||||
return openDownloadOutputStreamPipe(index, extension);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private InputStreamPipe openCacheInputStreamPipe(int index) {
|
||||
if (sCache == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
var snapshot = sCache.get(key);
|
||||
if (snapshot == null) return null;
|
||||
return new InputStreamPipe() {
|
||||
private InputStream is = null;
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
snapshot.close();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public InputStream open() throws IOException {
|
||||
if (is != null) IOUtils.closeQuietly(is);
|
||||
is = new FileInputStream(snapshot.getData().toFile());
|
||||
return is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (is != null) IOUtils.closeQuietly(is);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public InputStreamPipe openDownloadInputStreamPipe(int index) {
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
UniFile file = findImageFile(dir, index);
|
||||
private fun openDownloadInputStreamPipe(index: Int): InputStreamPipe? {
|
||||
val dir = downloadDir ?: return null
|
||||
for (i in 0..1) {
|
||||
val file = findImageFile(dir, index)
|
||||
if (file != null) {
|
||||
return new UniFileInputStreamPipe(file);
|
||||
return UniFileInputStreamPipe(file)
|
||||
} else if (!copyFromCacheToDownloadDir(index)) {
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public InputStreamPipe openInputStreamPipe(int index) {
|
||||
if (mMode == SpiderQueen.MODE_READ) {
|
||||
InputStreamPipe pipe = openCacheInputStreamPipe(index);
|
||||
if (pipe == null) {
|
||||
pipe = openDownloadInputStreamPipe(index);
|
||||
fun openInputStreamPipe(index: Int): InputStreamPipe? {
|
||||
return when (mMode) {
|
||||
SpiderQueen.MODE_READ -> {
|
||||
var pipe = openCacheInputStreamPipe(index)
|
||||
if (pipe == null) {
|
||||
pipe = openDownloadInputStreamPipe(index)
|
||||
}
|
||||
pipe
|
||||
}
|
||||
|
||||
SpiderQueen.MODE_DOWNLOAD -> {
|
||||
openDownloadInputStreamPipe(index)
|
||||
}
|
||||
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
return pipe;
|
||||
} else if (mMode == SpiderQueen.MODE_DOWNLOAD) {
|
||||
return openDownloadInputStreamPipe(index);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Image.ByteBufferSource getImageSource(int index) {
|
||||
fun getImageSource(index: Int): ByteBufferSource? {
|
||||
if (mMode == SpiderQueen.MODE_READ) {
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
if (sCache != null) {
|
||||
var snapshot = sCache.get(key);
|
||||
if (snapshot != null) {
|
||||
try {
|
||||
var file = new RandomAccessFile(snapshot.getData().toFile(), "rw");
|
||||
var chan = file.getChannel();
|
||||
var map = chan.map(FileChannel.MapMode.PRIVATE, 0, file.length());
|
||||
return new Image.ByteBufferSource() {
|
||||
@NonNull
|
||||
@Override
|
||||
public ByteBuffer getByteBuffer() {
|
||||
return map;
|
||||
}
|
||||
val key = EhCacheKeyFactory.getImageKey(mGid, index)
|
||||
val snapshot: DiskCache.Snapshot? = sCache[key]
|
||||
if (snapshot != null) {
|
||||
try {
|
||||
val file = RandomAccessFile(snapshot.data.toFile(), "rw")
|
||||
val chan = file.channel
|
||||
val map = chan.map(FileChannel.MapMode.PRIVATE, 0, file.length())
|
||||
return object : ByteBufferSource {
|
||||
override fun getByteBuffer(): ByteBuffer {
|
||||
return map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
chan.close();
|
||||
file.close();
|
||||
snapshot.close();
|
||||
}
|
||||
};
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
@Throws(Exception::class)
|
||||
override fun close() {
|
||||
chan.close()
|
||||
file.close()
|
||||
snapshot.close()
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return null;
|
||||
}
|
||||
UniFile file = findImageFile(dir, index);
|
||||
val dir = downloadDir ?: return null
|
||||
var file = findImageFile(dir, index)
|
||||
if (file != null && mMode == SpiderQueen.MODE_DOWNLOAD) {
|
||||
if (copyFromCacheToDownloadDir(index)) {
|
||||
file = findImageFile(dir, index);
|
||||
file = findImageFile(dir, index)
|
||||
}
|
||||
}
|
||||
if (file instanceof RawFile rawFile) {
|
||||
if (file is RawFile) {
|
||||
try {
|
||||
var file2 = new RandomAccessFile(rawFile.mFile, "rw");
|
||||
var chan = file2.getChannel();
|
||||
var map = chan.map(FileChannel.MapMode.PRIVATE, 0, file2.length());
|
||||
return new Image.ByteBufferSource() {
|
||||
@NonNull
|
||||
@Override
|
||||
public ByteBuffer getByteBuffer() {
|
||||
return map;
|
||||
val file2 = RandomAccessFile(file.mFile, "rw")
|
||||
val chan = file2.channel
|
||||
val map = chan.map(FileChannel.MapMode.PRIVATE, 0, file2.length())
|
||||
return object : ByteBufferSource {
|
||||
override fun getByteBuffer(): ByteBuffer {
|
||||
return map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
chan.close();
|
||||
file2.close();
|
||||
@Throws(Exception::class)
|
||||
override fun close() {
|
||||
chan.close()
|
||||
file2.close()
|
||||
}
|
||||
};
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
if (file != null) {
|
||||
try {
|
||||
var pfd = EhApplication.getApplication().getContentResolver().openFileDescriptor(file.getUri(), "rw");
|
||||
var map = Native.mapFd(pfd.getFd(), pfd.getStatSize());
|
||||
val pfd = application.contentResolver.openFileDescriptor(file.uri, "rw")
|
||||
val map = mapFd(pfd!!.fd, pfd.statSize)
|
||||
if (map != null) {
|
||||
return new Image.ByteBufferSource() {
|
||||
@NonNull
|
||||
@Override
|
||||
public ByteBuffer getByteBuffer() {
|
||||
return map;
|
||||
return object : ByteBufferSource {
|
||||
override fun getByteBuffer(): ByteBuffer {
|
||||
return map
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
Native.unmapDirectByteBuffer(map);
|
||||
pfd.close();
|
||||
@Throws(Exception::class)
|
||||
override fun close() {
|
||||
unmapDirectByteBuffer(map)
|
||||
pfd.close()
|
||||
}
|
||||
};
|
||||
}
|
||||
} else {
|
||||
pfd.close();
|
||||
pfd.close()
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// We use data to store image file, and metadata for image type
|
||||
private val sCache by lazy {
|
||||
DiskCache.Builder().directory(File(application.cacheDir, "gallery_image"))
|
||||
.maxSizeBytes(
|
||||
MathUtils.clamp(Settings.getReadCacheSize(), 40, 1280).toLong() * 1024 * 1024
|
||||
).build()
|
||||
}
|
||||
|
||||
fun getGalleryDownloadDir(gid: Long): UniFile? {
|
||||
val dir = Settings.getDownloadLocation()
|
||||
// Read from DB
|
||||
var dirname = EhDB.getDownloadDirname(gid)
|
||||
return if (dir != null && dirname != null) {
|
||||
// Some dirname may be invalid in some version
|
||||
dirname = FileUtils.sanitizeFilename(dirname)
|
||||
EhDB.putDownloadDirname(gid, dirname)
|
||||
dir.subFile(dirname)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extension with dot
|
||||
*/
|
||||
fun generateImageFilename(index: Int, extension: String?): String {
|
||||
return String.format(Locale.US, "%08d%s", index + 1, extension)
|
||||
}
|
||||
|
||||
private fun findImageFile(dir: UniFile, index: Int): UniFile? {
|
||||
for (extension in PageLoader2.SUPPORT_IMAGE_EXTENSIONS) {
|
||||
val filename = generateImageFilename(index, extension)
|
||||
val file = dir.findFile(filename)
|
||||
if (file != null) {
|
||||
return file
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user