2003/11/03 07:36:40
[org.ibex.core.git] / src / org / xwt / util / CachedInputStream.java
index 1c2cffd..a599459 100644 (file)
@@ -1,6 +1,7 @@
 package org.xwt.util;
 import java.io.*;
 
+// FEATURE: don't use a byte[] if we have a diskCache file
 /**
  *  Wraps around an InputStream, caching the stream in a byte[] as it
  *  is read and permitting multiple simultaneous readers
@@ -12,9 +13,19 @@ public class CachedInputStream {
     byte[] cache = new byte[1024 * 128];
     int size = 0;
     final InputStream is;
+    File diskCache;
 
-    public CachedInputStream(InputStream is) { this.is = is; }
-    public InputStream getInputStream() { return new SubStream(); }
+    public CachedInputStream(InputStream is) { this(is, null); }
+    public CachedInputStream(InputStream is, File diskCache) {
+        this.is = is;
+        this.diskCache = diskCache;
+    }
+    public InputStream getInputStream() throws IOException {
+        System.out.println("diskCache == " + diskCache);
+        System.out.println("diskCache.exists() == " + diskCache.exists());
+        if (diskCache != null && diskCache.exists()) return new FileInputStream(diskCache);
+        return new SubStream();
+    }
 
     public void grow(int newLength) {
         if (newLength < cache.length) return;
@@ -28,20 +39,35 @@ public class CachedInputStream {
         filling = true;
         grow(size + howMuch);
         int ret = is.read(cache, size, howMuch);
-        if (ret == -1) eof = true;
+        if (ret == -1) {
+            eof = true;
+            // FIXME: probably a race here
+            if (diskCache != null && !diskCache.exists())
+                try {
+                    File cacheFile = new File(diskCache + ".tmp");
+                    FileOutputStream cacheFileStream = new FileOutputStream(cacheFile);
+                    cacheFileStream.write(cache, 0, size);
+                    cacheFileStream.close();
+                    cacheFile.renameTo(diskCache);
+                } catch (IOException e) {
+                    Log.log(this, "exception thrown while writing disk cache");
+                    Log.log(this, e);
+                }
+        }
         else size += ret;
         filling = false;
         notifyAll();
     }
 
-    private class SubStream extends InputStream {
+    private class SubStream extends InputStream implements KnownLength {
         int pos = 0;
         public int available() { return Math.max(0, size - pos); }
         public long skip(long n) throws IOException { pos += (int)n; return n; }     // FEATURE: don't skip past EOF
+        public int getLength() { return eof ? size : is instanceof KnownLength ? ((KnownLength)is).getLength() : 0; }
         public int read() throws IOException {                                       // FEATURE: be smarter here
             byte[] b = new byte[1];
             int ret = read(b, 0, 1);
-            return ret == -1 ? -1 : b[0];
+            return ret == -1 ? -1 : b[0]&0xff;
         }
         public int read(byte[] b, int off, int len) throws IOException {
             synchronized(CachedInputStream.this) {
@@ -49,6 +75,7 @@ public class CachedInputStream {
                 if (eof && pos == size) return -1;
                 int count = Math.min(size - pos, len);
                 System.arraycopy(cache, pos, b, off, count);
+                pos += count;
                 return count;
             }
         }