You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2010/12/19 09:53:36 UTC

svn commit: r1050775 - in /poi/trunk/src: java/org/apache/poi/poifs/filesystem/ java/org/apache/poi/poifs/nio/ java/org/apache/poi/util/ testcases/org/apache/poi/poifs/filesystem/ testcases/org/apache/poi/poifs/nio/

Author: nick
Date: Sun Dec 19 08:53:36 2010
New Revision: 1050775

URL: http://svn.apache.org/viewvc?rev=1050775&view=rev
Log:
Change how the NIO block read works, to re-use the byte array for the from-InputStream case. Also start on reading the FAT blocks for NPOIFSFileSystem

Modified:
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java
    poi/trunk/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java
    poi/trunk/src/java/org/apache/poi/poifs/nio/DataSource.java
    poi/trunk/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java
    poi/trunk/src/java/org/apache/poi/util/IOUtils.java
    poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java
    poi/trunk/src/testcases/org/apache/poi/poifs/nio/TestDataSource.java

Modified: poi/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java?rev=1050775&r1=1050774&r2=1050775&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java Sun Dec 19 08:53:36 2010
@@ -184,12 +184,18 @@ public class NPOIFSFileSystem
            _header = new HeaderBlock(headerBuffer);
    
            // We need to buffer the whole file into memory when
-           //  working with an InputStream. Do so now
-           int maxSize = _header.getBATCount() * 
+           //  working with an InputStream.
+           // The max possible size is when each BAT block entry is used
+           int maxSize = 
+                 _header.getBATCount() * 
                  _header.getBigBlockSize().getBATEntriesPerBlock() *
-                 _header.getBigBlockSize().getBigBlockSize();
+                 _header.getBigBlockSize().getBigBlockSize()
+           ;
            ByteBuffer data = ByteBuffer.allocate(maxSize);
+           // Copy in the header
            data.put(headerBuffer);
+           data.position(_header.getBigBlockSize().getBigBlockSize());
+           // Now read the rest of the stream
            IOUtils.readFully(channel, data);
            success = true;
            
@@ -260,14 +266,46 @@ public class NPOIFSFileSystem
        // Grab the block size
        bigBlockSize = _header.getBigBlockSize();
        
-       // Read the properties
-       // TODO
-       
        // Read the FAT blocks
-       // TODO
+       for(int fatAT : _header.getBATArray()) {
+          ByteBuffer fatData = getBlockAt(fatAT);
+          _blocks.add(BATBlock.createBATBlock(bigBlockSize, fatData));
+       }
        
        // Now read the XFAT blocks
+// TODO Corrupt / Loop checking       
+       BATBlock xfat; 
+       int nextAt = _header.getXBATIndex();
+       for(int i=0; i<_header.getXBATCount(); i++) {
+          ByteBuffer fatData = getBlockAt(nextAt);
+          xfat = BATBlock.createBATBlock(bigBlockSize, fatData);
+          nextAt = xfat.getValueAt(bigBlockSize.getNextXBATChainOffset());
+          
+          _blocks.add(xfat);
+       }
+       
+       // We're now able to load steams
+       // Use this to read in the properties
+       // TODO
+// TODO With loop checking
+    }
+    
+    /**
+     * Load the block at the given offset.
+     */
+    protected ByteBuffer getBlockAt(final int offset) throws IOException {
+       ByteBuffer data = ByteBuffer.allocate(bigBlockSize.getBigBlockSize());
+       
+       // The header block doesn't count, so add one
+       long startAt = (offset+1) * bigBlockSize.getBigBlockSize();
+       return _data.read(bigBlockSize.getBigBlockSize(), startAt);
+    }
+    /**
+     * Works out what block follows the specified one.
+     */
+    protected int getNextBlock(final int offset) {
        // TODO
+       return -1;
     }
 
     /**

Modified: poi/trunk/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java?rev=1050775&r1=1050774&r2=1050775&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java Sun Dec 19 08:53:36 2010
@@ -34,16 +34,16 @@ public class ByteArrayBackedDataSource e
       this(data, data.length);
    }
                 
-   public void read(ByteBuffer dst, long position) {
+   public ByteBuffer read(int length, long position) {
       if(position >= size) {
          throw new IndexOutOfBoundsException(
-               "Unable to read " + dst.capacity() + " bytes from " +
+               "Unable to read " + length + " bytes from " +
                position + " in stream of length " + size
          );
       }
       
-      int toRead = (int)Math.min(dst.capacity(), size - position);
-      dst.put(buffer, (int)position, toRead);
+      int toRead = (int)Math.min(length, size - position);
+      return ByteBuffer.wrap(buffer, (int)position, toRead);
    }
    
    public void write(ByteBuffer src, long position) {

Modified: poi/trunk/src/java/org/apache/poi/poifs/nio/DataSource.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/nio/DataSource.java?rev=1050775&r1=1050774&r2=1050775&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/nio/DataSource.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/nio/DataSource.java Sun Dec 19 08:53:36 2010
@@ -24,8 +24,8 @@ import java.nio.ByteBuffer;
  * Common definition of how we read and write bytes
  */
 public abstract class DataSource {
-   abstract void read(ByteBuffer dst, long position) throws IOException;
-   abstract void write(ByteBuffer src, long position) throws IOException;
-   abstract long size() throws IOException;
-   abstract void close() throws IOException;
+   public abstract ByteBuffer read(int length, long position) throws IOException;
+   public abstract void write(ByteBuffer src, long position) throws IOException;
+   public abstract long size() throws IOException;
+   public abstract void close() throws IOException;
 }

Modified: poi/trunk/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java?rev=1050775&r1=1050774&r2=1050775&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java Sun Dec 19 08:53:36 2010
@@ -42,17 +42,26 @@ public class FileBackedDataSource extend
       this.channel = channel;
    }
    
-   public void read(ByteBuffer dst, long position) throws IOException {
+   public ByteBuffer read(int length, long position) throws IOException {
       if(position >= size()) {
          throw new IllegalArgumentException("Position " + position + " past the end of the file");
       }
-      
+
+      // Read
       channel.position(position);
+      ByteBuffer dst = ByteBuffer.allocate(length);
       int worked = IOUtils.readFully(channel, dst);
       
+      // Check
       if(worked == -1) {
          throw new IllegalArgumentException("Position " + position + " past the end of the file");
       }
+      
+      // Ready it for reading
+      dst.position(0);
+      
+      // All done
+      return dst;
    }
    
    public void write(ByteBuffer src, long position) throws IOException {

Modified: poi/trunk/src/java/org/apache/poi/util/IOUtils.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/util/IOUtils.java?rev=1050775&r1=1050774&r2=1050775&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/util/IOUtils.java (original)
+++ poi/trunk/src/java/org/apache/poi/util/IOUtils.java Sun Dec 19 08:53:36 2010
@@ -105,7 +105,7 @@ public final class IOUtils {
 	public static int readFully(ReadableByteChannel channel, ByteBuffer b) throws IOException {
       int total = 0;
       while (true) {
-         int got = channel.read(b); 
+         int got = channel.read(b);
          if (got < 0) {
             return (total == 0) ? -1 : total;
          }

Modified: poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java?rev=1050775&r1=1050774&r2=1050775&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java Sun Dec 19 08:53:36 2010
@@ -55,5 +55,30 @@ public final class TestNPOIFSFileSystem 
          assertEquals(4096, fs.getBigBlockSize());
       }
    }
-   
+
+   public void testPropertiesAndFatOnRead() throws Exception {
+      NPOIFSFileSystem fsA, fsB;
+      
+      // With a simple 512 block file
+      fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize512.zvi"));
+      fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize512.zvi"));
+      for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
+         // Check the FAT was properly processed
+         // TODO
+         
+         // Check the properties
+         // TODO
+      }
+      
+      // Now with a simple 4096 block file
+      fsA = new NPOIFSFileSystem(_inst.getFile("BlockSize4096.zvi"));
+      fsB = new NPOIFSFileSystem(_inst.openResourceAsStream("BlockSize4096.zvi"));
+      for(NPOIFSFileSystem fs : new NPOIFSFileSystem[] {fsA,fsB}) {
+         // Check the FAT was properly processed
+         // TODO
+         
+         // Check the properties
+         // TODO
+      }
+   }
 }

Modified: poi/trunk/src/testcases/org/apache/poi/poifs/nio/TestDataSource.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/nio/TestDataSource.java?rev=1050775&r1=1050774&r2=1050775&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/nio/TestDataSource.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/nio/TestDataSource.java Sun Dec 19 08:53:36 2010
@@ -20,6 +20,7 @@
 package org.apache.poi.poifs.nio;
 
 import java.io.File;
+import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
 
 import org.apache.poi.POIDataSamples;
@@ -40,20 +41,23 @@ public class TestDataSource extends Test
       assertEquals(8192, ds.size());
       
       // Start of file
-      ByteBuffer bs = ByteBuffer.allocate(4); 
-      ds.read(bs, 0);
+      ByteBuffer bs; 
+      bs = ds.read(4, 0);
       assertEquals(4, bs.capacity());
-      assertEquals(4, bs.position());
+      assertEquals(0, bs.position());
       assertEquals(0xd0-256, bs.get(0));
       assertEquals(0xcf-256, bs.get(1));
       assertEquals(0x11-000, bs.get(2));
       assertEquals(0xe0-256, bs.get(3));
+      assertEquals(0xd0-256, bs.get());
+      assertEquals(0xcf-256, bs.get());
+      assertEquals(0x11-000, bs.get());
+      assertEquals(0xe0-256, bs.get());
       
       // Mid way through
-      bs = ByteBuffer.allocate(8);
-      ds.read(bs, 0x400);
+      bs = ds.read(8, 0x400);
       assertEquals(8, bs.capacity());
-      assertEquals(8, bs.position());
+      assertEquals(0, bs.position());
       assertEquals((byte)'R', bs.get(0));
       assertEquals(0, bs.get(1));
       assertEquals((byte)'o', bs.get(2));
@@ -64,14 +68,12 @@ public class TestDataSource extends Test
       assertEquals(0, bs.get(7));
       
       // Can go to the end, but not past it
-      bs.clear();
-      ds.read(bs, 8190);
-      assertEquals(2, bs.position());
+      bs = ds.read(8, 8190);
+      assertEquals(0, bs.position()); // TODO How best to warn of a short read?
       
       // Can't go off the end
       try {
-         bs.clear();
-         ds.read(bs, 8192);
+         bs = ds.read(4, 8192);
          fail("Shouldn't be able to read off the end of the file");
       } catch(IllegalArgumentException e) {}
    }
@@ -87,70 +89,64 @@ public class TestDataSource extends Test
       ByteArrayBackedDataSource ds = new ByteArrayBackedDataSource(data);
       
       // Start
-      ByteBuffer bs = ByteBuffer.allocate(4); 
-      ds.read(bs, 0);
-      assertEquals(4, bs.capacity());
-      assertEquals(4, bs.position());
-      assertEquals(0x00, bs.get(0));
-      assertEquals(0x01, bs.get(1));
-      assertEquals(0x02, bs.get(2));
-      assertEquals(0x03, bs.get(3));
+      ByteBuffer bs; 
+      bs = ds.read(4, 0);
+      assertEquals(0, bs.position());
+      assertEquals(0x00, bs.get());
+      assertEquals(0x01, bs.get());
+      assertEquals(0x02, bs.get());
+      assertEquals(0x03, bs.get());
       
       // Middle
-      bs.clear(); 
-      ds.read(bs, 100);
-      assertEquals(4, bs.capacity());
-      assertEquals(4, bs.position());
-      assertEquals(100, bs.get(0));
-      assertEquals(101, bs.get(1));
-      assertEquals(102, bs.get(2));
-      assertEquals(103, bs.get(3));
+      bs = ds.read(4, 100);
+      assertEquals(100, bs.position());
+      assertEquals(100, bs.get());
+      assertEquals(101, bs.get());
+      assertEquals(102, bs.get());
+      assertEquals(103, bs.get());
       
       // End
-      bs.clear(); 
-      ds.read(bs, 252);
-      assertEquals(4, bs.capacity());
-      assertEquals(4, bs.position());
-      assertEquals(-4, bs.get(0));
-      assertEquals(-3, bs.get(1));
-      assertEquals(-2, bs.get(2));
-      assertEquals(-1, bs.get(3));
+      bs = ds.read(4, 252);
+      assertEquals(-4, bs.get());
+      assertEquals(-3, bs.get());
+      assertEquals(-2, bs.get());
+      assertEquals(-1, bs.get());
       
       // Off the end
-      bs.clear(); 
-      ds.read(bs, 254);
-      assertEquals(4, bs.capacity());
-      assertEquals(2, bs.position());
-      assertEquals(-2, bs.get(0));
-      assertEquals(-1, bs.get(1));
+      bs = ds.read(4, 254);
+      assertEquals(-2, bs.get());
+      assertEquals(-1, bs.get());
+      try {
+         bs.get();
+         fail("Shouldn't be able to read off the end");
+      } catch(BufferUnderflowException e) {}
 
       // Past the end
-      bs.clear(); 
       try {
-         ds.read(bs, 256);
+         bs = ds.read(4, 256);
          fail("Shouldn't be able to read off the end");
       } catch(IndexOutOfBoundsException e) {}
       
       
       // Overwrite
-      bs.clear();
+      bs = ByteBuffer.allocate(4);
       bs.put(0, (byte)-55);
       bs.put(1, (byte)-54);
       bs.put(2, (byte)-53);
       bs.put(3, (byte)-52);
       
+      assertEquals(256, ds.size());
       ds.write(bs, 40);
-      bs.clear();
-      ds.read(bs, 40);
+      assertEquals(256, ds.size());
+      bs = ds.read(4, 40);
       
-      assertEquals(4, bs.position());
-      assertEquals(-55, bs.get(0));
-      assertEquals(-54, bs.get(1));
-      assertEquals(-53, bs.get(2));
-      assertEquals(-52, bs.get(3));
+      assertEquals(-55, bs.get());
+      assertEquals(-54, bs.get());
+      assertEquals(-53, bs.get());
+      assertEquals(-52, bs.get());
       
       // Append
-      bs.clear();
+      bs = ByteBuffer.allocate(4);
       bs.put(0, (byte)-55);
       bs.put(1, (byte)-54);
       bs.put(2, (byte)-53);
@@ -160,12 +156,11 @@ public class TestDataSource extends Test
       ds.write(bs, 256);
       assertEquals(260, ds.size());
       
-      bs.clear();
-      ds.read(bs, 256);
-      assertEquals(4, bs.position());
-      assertEquals(-55, bs.get(0));
-      assertEquals(-54, bs.get(1));
-      assertEquals(-53, bs.get(2));
-      assertEquals(-52, bs.get(3));
+      bs = ds.read(4, 256);
+      assertEquals(256, bs.position());
+      assertEquals(-55, bs.get());
+      assertEquals(-54, bs.get());
+      assertEquals(-53, bs.get());
+      assertEquals(-52, bs.get());
    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org