diff --git a/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt b/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt index 03bcb8179..cb8743eec 100644 --- a/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt +++ b/app/src/main/java/com/hippo/ehviewer/spider/SpiderDen.kt @@ -302,25 +302,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) { file = findImageFile(dir, index) } } - if (file is RawFile) { - val source = ImageDecoder.createSource(file.mFile) - return object : CloseableSource { - override val source: ImageDecoder.Source - get() = source - - override fun close() {} - } - } - if (file != null) { - val source = ImageDecoder.createSource(contentResolver, file.uri) - return object : CloseableSource { - override val source: ImageDecoder.Source - get() = source - - override fun close() {} - } - } - return null + return file?.imageSource } companion object { diff --git a/app/src/main/java/com/hippo/unifile/Contracts.java b/app/src/main/java/com/hippo/unifile/Contracts.java index 82f0e0433..7a2a1e45f 100644 --- a/app/src/main/java/com/hippo/unifile/Contracts.java +++ b/app/src/main/java/com/hippo/unifile/Contracts.java @@ -19,10 +19,13 @@ package com.hippo.unifile; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; +import android.graphics.ImageDecoder; import android.net.Uri; import androidx.annotation.NonNull; +import com.hippo.image.Image; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -117,4 +120,20 @@ final class Contracts { throw new IOException("Can't open InputStream", e); } } + + @NonNull + static Image.CloseableSource getImageSource(Context context, Uri uri) { + var source = ImageDecoder.createSource(context.getContentResolver(), uri); + return new Image.CloseableSource() { + @NonNull + @Override + public ImageDecoder.Source getSource() { + return source; + } + + @Override + public void close() { + } + }; + } } diff --git a/app/src/main/java/com/hippo/unifile/FileDescriptorRandomAccessFile.java b/app/src/main/java/com/hippo/unifile/FileDescriptorRandomAccessFile.java deleted file mode 100644 index 7c0e218ab..000000000 --- a/app/src/main/java/com/hippo/unifile/FileDescriptorRandomAccessFile.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2016 Hippo Seven - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.unifile; - -import android.content.Context; -import android.net.Uri; -import android.os.ParcelFileDescriptor; -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; - -import androidx.annotation.IntDef; -import androidx.annotation.NonNull; - -import java.io.FileDescriptor; -import java.io.IOException; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -class FileDescriptorRandomAccessFile implements UniRandomAccessFile { - - public static final int FLUSH_NONE = 0; - public static final int FLUSH_FSYNC = 1; - public static final int FLUSH_FDATASYNC = 2; - private final ParcelFileDescriptor pfd; - private final FileDescriptor fd; - private final int flushAfterWrite; - private final Object closeLock = new Object(); - private volatile boolean closed = false; - - private FileDescriptorRandomAccessFile(ParcelFileDescriptor pfd, FileDescriptor fd, String mode) { - this.pfd = pfd; - this.fd = fd; - - switch (mode) { - case "rws": - flushAfterWrite = FLUSH_FSYNC; - break; - case "rwd": - flushAfterWrite = FLUSH_FDATASYNC; - break; - default: - flushAfterWrite = FLUSH_NONE; - break; - } - } - - @NonNull - static FileDescriptorRandomAccessFile create(Context context, Uri uri, String mode) throws IOException { - // Get FileDescriptor - ParcelFileDescriptor pfd; - try { - pfd = context.getContentResolver().openFileDescriptor(uri, mode); - } catch (Throwable e) { - Utils.throwIfFatal(e); - throw new IOException("Can't get ParcelFileDescriptor", e); - } - if (pfd == null) { - throw new IOException("Can't get ParcelFileDescriptor"); - } - FileDescriptor fd; - try { - fd = pfd.getFileDescriptor(); - } catch (SecurityException e) { - pfd.close(); - throw new IOException("Can't get FileDescriptor", e); - } - if (fd == null) { - pfd.close(); - throw new IOException("Can't get FileDescriptor"); - } - - return new FileDescriptorRandomAccessFile(pfd, fd, mode); - } - - private void maybeSync() { - if (flushAfterWrite == FLUSH_FSYNC) { - try { - fd.sync(); - } catch (IOException e) { - // Ignored - } - } else if (flushAfterWrite == FLUSH_FDATASYNC) { - try { - Os.fdatasync(fd); - } catch (ErrnoException e) { - // Ignored - } - } - } - - @Override - public void close() throws IOException { - synchronized (closeLock) { - if (closed) { - return; - } - closed = true; - } - - pfd.close(); - - try { - Os.close(fd); - } catch (ErrnoException e) { - throw new IOException("An ErrnoException occurs", e); - } - } - - @Override - public long getFilePointer() throws IOException { - try { - return Os.lseek(fd, 0L, OsConstants.SEEK_CUR); - } catch (ErrnoException e) { - throw new IOException("An ErrnoException occurs", e); - } - } - - @Override - public void seek(long pos) throws IOException { - if (pos < 0) { - throw new IOException("offset < 0: " + pos); - } else { - try { - Os.lseek(fd, pos, OsConstants.SEEK_SET); - } catch (ErrnoException e) { - throw new IOException("An ErrnoException occurs", e); - } - } - } - - @Override - public int skipBytes(int n) throws IOException { - long pos; - long len; - long newpos; - - if (n <= 0) { - return 0; - } - pos = getFilePointer(); - len = length(); - newpos = pos + n; - if (newpos > len) { - newpos = len; - } - seek(newpos); - - /* return the actual number of bytes skipped */ - return (int) (newpos - pos); - } - - @Override - public long length() throws IOException { - try { - return Os.fstat(fd).st_size; - } catch (ErrnoException e) { - throw new IOException("An ErrnoException occurs", e); - } - } - - @Override - public void setLength(long newLength) throws IOException { - if (newLength < 0) { - throw new IllegalArgumentException("newLength < 0"); - } - try { - Os.ftruncate(fd, newLength); - } catch (ErrnoException e) { - throw new IOException("An ErrnoException occurs", e); - } - - long filePointer = getFilePointer(); - if (filePointer > newLength) { - seek(newLength); - } - - maybeSync(); - } - - @Override - public int read(byte[] b) throws IOException { - return read(b, 0, b.length); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - try { - return Os.read(fd, b, off, len); - } catch (ErrnoException e) { - throw new IOException("An ErrnoException occurs", e); - } - } - - @Override - public void write(byte[] b) throws IOException { - write(b, 0, b.length); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - try { - Os.write(fd, b, off, len); - } catch (ErrnoException e) { - throw new IOException("An ErrnoException occurs", e); - } - maybeSync(); - } - - @IntDef({FLUSH_NONE, FLUSH_FSYNC, FLUSH_FDATASYNC}) - @Retention(RetentionPolicy.SOURCE) - public @interface FlushMode { - } -} diff --git a/app/src/main/java/com/hippo/unifile/MediaFile.java b/app/src/main/java/com/hippo/unifile/MediaFile.java index 7e3045015..5521e0258 100644 --- a/app/src/main/java/com/hippo/unifile/MediaFile.java +++ b/app/src/main/java/com/hippo/unifile/MediaFile.java @@ -21,6 +21,8 @@ import android.net.Uri; import androidx.annotation.NonNull; +import com.hippo.image.Image; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -187,7 +189,7 @@ class MediaFile extends UniFile { @NonNull @Override - public UniRandomAccessFile createRandomAccessFile(String mode) throws IOException { - return FileDescriptorRandomAccessFile.create(mContext, mUri, mode); + public Image.CloseableSource getImageSource() { + return Contracts.getImageSource(mContext, mUri); } } diff --git a/app/src/main/java/com/hippo/unifile/RawFile.java b/app/src/main/java/com/hippo/unifile/RawFile.java index bf95e5679..3fd8d5092 100644 --- a/app/src/main/java/com/hippo/unifile/RawFile.java +++ b/app/src/main/java/com/hippo/unifile/RawFile.java @@ -16,20 +16,21 @@ package com.hippo.unifile; +import android.graphics.ImageDecoder; import android.net.Uri; import android.util.Log; import android.webkit.MimeTypeMap; import androidx.annotation.NonNull; +import com.hippo.image.Image; + import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.RandomAccessFile; import java.util.ArrayList; public class RawFile extends UniFile { @@ -264,9 +265,21 @@ public class RawFile extends UniFile { return new FileInputStream(mFile); } - @Override @NonNull - public UniRandomAccessFile createRandomAccessFile(String mode) throws FileNotFoundException { - return new RawRandomAccessFile(new RandomAccessFile(mFile, mode)); + @Override + public Image.CloseableSource getImageSource() { + var src = ImageDecoder.createSource(mFile); + return new Image.CloseableSource() { + @NonNull + @Override + public ImageDecoder.Source getSource() { + return src; + } + + @Override + public void close() { + + } + }; } } diff --git a/app/src/main/java/com/hippo/unifile/RawRandomAccessFile.java b/app/src/main/java/com/hippo/unifile/RawRandomAccessFile.java deleted file mode 100644 index e9114fa43..000000000 --- a/app/src/main/java/com/hippo/unifile/RawRandomAccessFile.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2016 Hippo Seven - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.unifile; - -/* - * Created by Hippo on 8/15/2016. - */ - -import java.io.IOException; -import java.io.RandomAccessFile; - -class RawRandomAccessFile implements UniRandomAccessFile { - - private final RandomAccessFile mFile; - - RawRandomAccessFile(RandomAccessFile file) { - mFile = file; - } - - @Override - public void close() throws IOException { - mFile.close(); - } - - @Override - public long getFilePointer() throws IOException { - return mFile.getFilePointer(); - } - - @Override - public void seek(long pos) throws IOException { - mFile.seek(pos); - } - - @Override - public int skipBytes(int n) throws IOException { - return mFile.skipBytes(n); - } - - @Override - public long length() throws IOException { - return mFile.length(); - } - - @Override - public void setLength(long newLength) throws IOException { - mFile.setLength(newLength); - } - - @Override - public int read(byte[] b) throws IOException { - return mFile.read(b); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - return mFile.read(b, off, len); - } - - @Override - public void write(byte[] b) throws IOException { - mFile.write(b); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - mFile.write(b, off, len); - } -} diff --git a/app/src/main/java/com/hippo/unifile/SingleDocumentFile.java b/app/src/main/java/com/hippo/unifile/SingleDocumentFile.java index 9c93ed4c4..a03e1c8b1 100644 --- a/app/src/main/java/com/hippo/unifile/SingleDocumentFile.java +++ b/app/src/main/java/com/hippo/unifile/SingleDocumentFile.java @@ -21,6 +21,8 @@ import android.net.Uri; import androidx.annotation.NonNull; +import com.hippo.image.Image; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -168,11 +170,7 @@ class SingleDocumentFile extends UniFile { @NonNull @Override - public UniRandomAccessFile createRandomAccessFile(String mode) throws IOException { - // Check file - if (!ensureFile()) { - throw new IOException("Can't make sure it is file"); - } - return FileDescriptorRandomAccessFile.create(mContext, mUri, mode); + public Image.CloseableSource getImageSource() { + return Contracts.getImageSource(mContext, mUri); } } diff --git a/app/src/main/java/com/hippo/unifile/TreeDocumentFile.java b/app/src/main/java/com/hippo/unifile/TreeDocumentFile.java index 1654578a5..d1efd410d 100644 --- a/app/src/main/java/com/hippo/unifile/TreeDocumentFile.java +++ b/app/src/main/java/com/hippo/unifile/TreeDocumentFile.java @@ -24,6 +24,8 @@ import android.webkit.MimeTypeMap; import androidx.annotation.NonNull; +import com.hippo.image.Image; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -267,12 +269,7 @@ class TreeDocumentFile extends UniFile { @NonNull @Override - public UniRandomAccessFile createRandomAccessFile(String mode) throws IOException { - // Check file - if (!ensureFile()) { - throw new IOException("Can't make sure it is file"); - } - - return FileDescriptorRandomAccessFile.create(mContext, mUri, mode); + public Image.CloseableSource getImageSource() { + return Contracts.getImageSource(mContext, mUri); } } diff --git a/app/src/main/java/com/hippo/unifile/UniFile.java b/app/src/main/java/com/hippo/unifile/UniFile.java index 543be1c9d..3abaebaba 100644 --- a/app/src/main/java/com/hippo/unifile/UniFile.java +++ b/app/src/main/java/com/hippo/unifile/UniFile.java @@ -25,6 +25,8 @@ import android.os.Build; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.hippo.image.Image; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -440,13 +442,7 @@ public abstract class UniFile { @NonNull public abstract InputStream openInputStream() throws IOException; - /** - * Get a random access stuff of the UniFile - * - * @param mode "r" or "rw" - * @return the random access stuff - * @throws IOException - */ + @NonNull - public abstract UniRandomAccessFile createRandomAccessFile(String mode) throws IOException; + public abstract Image.CloseableSource getImageSource(); } diff --git a/app/src/main/java/com/hippo/unifile/UniRandomAccessFile.java b/app/src/main/java/com/hippo/unifile/UniRandomAccessFile.java deleted file mode 100644 index defb72dc4..000000000 --- a/app/src/main/java/com/hippo/unifile/UniRandomAccessFile.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2016 Hippo Seven - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.unifile; - -/* - * Created by Hippo on 8/15/2016. - */ - -import java.io.IOException; - -/** - * The UniRandomAccessFile is designed to emulate RandomAccessFile interface for UniFile - */ -public interface UniRandomAccessFile { - - /** - * Closes this UniRandomAccessFile and releases any resources associated with it. - * A closed UniRandomAccessFile cannot perform any operations. - * - * @throws IOException - */ - void close() throws IOException; - - /** - * Returns the current offset in this file. - * - * @throws IOException - */ - long getFilePointer() throws IOException; - - /** - * Move current location pointer to the new offset. - * - * @param pos the offset position, measured in bytes from the beginning - * @throws IOException - */ - void seek(long pos) throws IOException; - - /** - * Attempts to skip over n bytes of input discarding the skipped bytes. - * - * @param n the number of bytes to be skipped - * @return the actual number of bytes skipped - * @throws IOException - */ - int skipBytes(int n) throws IOException; - - /** - * Returns the length of this file. - * - * @throws IOException - */ - long length() throws IOException; - - /** - * Sets the length of this file. - * - * @param newLength the desired length of the file - * @throws IOException - */ - void setLength(long newLength) throws IOException; - - /** - * Reads b.length bytes from this file into the byte array, - * starting at the current file pointer. - * - * @param b the buffer into which the data is read - * @return the total number of bytes read into the buffer, or - * {@code -1} if there is no more data because the end of - * the file has been reached. - * @throws IOException if an I/O error occurs - */ - int read(byte[] b) throws IOException; - - /** - * Reads exactly len bytes from this file into the byte array, - * starting at the current file pointer. - * - * @param b the buffer into which the data is read - * @param off the start offset of the data - * @param len the number of bytes to read - * @return the total number of bytes read into the buffer, or - * {@code -1} if there is no more data because the end of - * the file has been reached. - * @throws IOException - */ - int read(byte[] b, int off, int len) throws IOException; - - /** - * Writes b.length bytes from the specified byte array to this file, - * starting at the current file pointer. - * - * @param b the data - * @throws IOException - */ - void write(byte[] b) throws IOException; - - /** - * Writes len bytes from the specified byte array starting at offset off to this file. - * - * @param b the data - * @param off the start offset in the data - * @param len the number of bytes to write - * @throws IOException - */ - void write(byte[] b, int off, int len) throws IOException; -}