[libbluray-devel] java.io.FileInputStream: added suppport for reading files from Xlet home directory
hpi1
git at videolan.org
Mon Jan 20 23:58:28 CET 2014
libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Tue Jan 21 00:56:22 2014 +0200| [1d0f915891094f8147eca7010017f831362e1159] | committer: hpi1
java.io.FileInputStream: added suppport for reading files from Xlet home directory
> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=1d0f915891094f8147eca7010017f831362e1159
---
src/libbluray/bdj/java/java/io/FileDescriptor.java | 77 +++++++
.../bdj/java/java/io/FileInputStream.java | 217 ++++++++++++++++++++
2 files changed, 294 insertions(+)
diff --git a/src/libbluray/bdj/java/java/io/FileDescriptor.java b/src/libbluray/bdj/java/java/io/FileDescriptor.java
new file mode 100644
index 0000000..7676ca2
--- /dev/null
+++ b/src/libbluray/bdj/java/java/io/FileDescriptor.java
@@ -0,0 +1,77 @@
+/*
+ * This file is part of libbluray
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+package java.io;
+
+public final class FileDescriptor {
+
+ /* for files used by JVM */
+ private int fd;
+ private long handle;
+
+ /* for files in BD VFS */
+ private long fp;
+
+ /* for files inside .jar */
+ protected InputStream slave;
+
+ private int useCount;
+
+ public FileDescriptor() {
+ fd = -1;
+ handle = -1;
+ fp = 0;
+ slave = null;
+ useCount = 0;
+ }
+
+ private FileDescriptor(int fd) {
+ this();
+ this.fd = fd;
+ }
+
+ public static final FileDescriptor in = new FileDescriptor(0);
+ public static final FileDescriptor out = new FileDescriptor(1);
+ public static final FileDescriptor err = new FileDescriptor(2);
+
+ public boolean valid() {
+ return (fd != -1) || (handle != -1) || (fp != 0) || (slave != null);
+ }
+
+ public native void sync() throws SyncFailedException;
+
+ private static native void initIDs();
+
+ static {
+ initIDs();
+ }
+
+ int incrementAndGetUseCount() {
+ synchronized (this) {
+ useCount = useCount + 1;
+ return useCount;
+ }
+ }
+
+ int decrementAndGetUseCount() {
+ synchronized (this) {
+ useCount = useCount - 1;
+ return useCount;
+ }
+ }
+}
diff --git a/src/libbluray/bdj/java/java/io/FileInputStream.java b/src/libbluray/bdj/java/java/io/FileInputStream.java
new file mode 100644
index 0000000..aa74257
--- /dev/null
+++ b/src/libbluray/bdj/java/java/io/FileInputStream.java
@@ -0,0 +1,217 @@
+/*
+ * This file is part of libbluray
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+package java.io;
+
+import java.net.URL;
+//import java.nio.channels.FileChannel;
+
+import org.videolan.BDJXletContext;
+import org.videolan.Logger;
+
+public class FileInputStream extends InputStream
+{
+ private FileDescriptor fd;
+
+ private final Object closeLock = new Object();
+ private volatile boolean closed = false;
+
+ private static Logger logger = null;
+
+ private int available = 0;
+
+ public FileInputStream(File file) throws FileNotFoundException {
+ String name = file != null ? file.getPath() : null;
+
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkRead(name);
+ }
+ if (name == null) {
+ throw new NullPointerException();
+ }
+
+ fd = new FileDescriptor();
+ fd.incrementAndGetUseCount();
+
+ if (file.isAbsolute()) {
+ open(name);
+ } else {
+ /* relative paths are problematic ... */
+ /* Those should be mapped to xlet home directory, which is inside .jar file. */
+ openResource(name);
+ }
+
+ available = 1024;
+ }
+
+ public FileInputStream(String name) throws FileNotFoundException {
+ this(name != null ? new File(name) : null);
+ }
+
+ public FileInputStream(FileDescriptor fdObj) {
+ SecurityManager security = System.getSecurityManager();
+ if (fdObj == null) {
+ throw new NullPointerException();
+ }
+ if (security != null) {
+ security.checkRead(fdObj);
+ }
+ fdObj.incrementAndGetUseCount();
+ fd = fdObj;
+ available = 1024;
+ }
+
+ private void openResource(String name) throws FileNotFoundException {
+ if (logger == null) {
+ logger = Logger.getLogger(FileInputStream.class.getName());
+ }
+
+ /* J2SE URL.getPath() returns file:/xxx.jar!/... for jar resource urls ... */
+ if (name.indexOf("file:/") == 0 && name.indexOf(".jar!/") > 0) {
+ logger.error("Fixing invalid resource url: " + name);
+ name = name.substring(name.indexOf(".jar!") + 6);
+ }
+
+ /* try to locate file in Xlet home directory (inside JAR file) */
+
+ ClassLoader cldr = (ClassLoader)BDJXletContext.getCurrentClassLoader();
+ if (cldr == null) {
+ throw new FileNotFoundException(name);
+ }
+
+ if (name.startsWith("./") || name.startsWith(".\\")) {
+ name = name.substring(2);
+ }
+
+ URL url = cldr.getResource(name);
+ if (url == null) {
+ logger.error("Resource not found: " + name);
+ throw new FileNotFoundException(name);
+ }
+ logger.info(name + " translated to " + url);
+
+ fd.slave = cldr.getResourceAsStream(name);
+ if (fd.slave == null) {
+ logger.error("Error getting resource as stream");
+ throw new FileNotFoundException(name);
+ }
+ }
+
+
+ private native void open(String name) throws FileNotFoundException;
+ private native int readBytes(byte b[], int off, int len) throws IOException;
+ private native int close0();
+
+ //public native int read() throws IOException;
+ //public native long skip(long n) throws IOException;
+ //public native int available() throws IOException;
+
+ public int available() throws IOException {
+ if (fd != null && fd.slave != null) {
+ return fd.slave.available();
+ }
+ return available;
+ }
+
+ public int read() throws IOException {
+ byte b[] = new byte[1];
+ if (read(b) == 1)
+ return b[0];
+ return -1;
+ }
+
+ public int read(byte b[]) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ public int read(byte b[], int off, int len) throws IOException {
+ if (b == null) {
+ throw new NullPointerException();
+ }
+ if (off < 0 || len < 0 || off > b.length || (off + len) > b.length || (off + len) < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+
+ if (fd != null && fd.slave != null) {
+ return fd.slave.read(b, off, len);
+ }
+
+ int r = readBytes(b, off, len);
+ if (r != len) {
+ available = 0;
+ }
+ return r;
+ }
+
+ public long skip(long n) throws IOException {
+ return super.skip(n);
+ }
+
+ public void close() throws IOException {
+ close(true);
+ }
+
+ public void close(boolean force) throws IOException {
+ synchronized (closeLock) {
+ if (closed) {
+ return;
+ }
+ closed = true;
+ }
+
+ available = 0;
+
+ if (fd != null && fd.slave != null) {
+ fd.slave.close();
+ return;
+ }
+
+ int n = fd.decrementAndGetUseCount();
+ if (n > 0 && !force) {
+ return;
+ }
+
+ close0();
+ }
+
+ public final FileDescriptor getFD() throws IOException {
+ if (fd == null) {
+ throw new IOException();
+ }
+ return fd;
+ }
+
+ /* not in J2SE
+ public FileChannel getChannel() {}
+ */
+
+ private static native void initIDs();
+
+ static {
+ initIDs();
+ }
+
+ protected void finalize() throws IOException {
+ if (fd != null) {
+ if (fd != fd.in) {
+ close(false);
+ }
+ }
+ }
+}
More information about the libbluray-devel
mailing list