Move getImageSource to UniFile interface, and remove UniRandomAccessFile, it's a suck design
This commit is contained in:
1 parent
c4a3f06b51
commit
24ccf60870
10 files changed
+54
-479
No files matched your search
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user