]> source.dussan.org Git - poi.git/commitdiff
Tests and tweaks to the NIO DataSource code
authorNick Burch <nick@apache.org>
Sun, 19 Dec 2010 04:59:49 +0000 (04:59 +0000)
committerNick Burch <nick@apache.org>
Sun, 19 Dec 2010 04:59:49 +0000 (04:59 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1050758 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java
src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java
src/testcases/org/apache/poi/poifs/nio/TestDataSource.java

index 8fbb3ce102abb0bba0d6451f2cd0f95ffe9dc982..4e368994bb8cd8c7a4bdfe81f20477f4abfe55d9 100644 (file)
@@ -32,13 +32,15 @@ public class ByteArrayBackedDataSource extends DataSource {
    }
                 
    public void read(ByteBuffer dst, long position) {
-      if(position + dst.capacity() > size) {
+      if(position >= size) {
          throw new IndexOutOfBoundsException(
                "Unable to read " + dst.capacity() + " bytes from " +
                position + " in stream of length " + size
          );
       }
-      dst.put(buffer, (int)position, dst.capacity());
+      
+      int toRead = (int)Math.min(dst.capacity(), size - position);
+      dst.put(buffer, (int)position, toRead);
    }
    
    public void write(ByteBuffer src, long position) {
index 7f5e8e63545055f2d91b515c9dc5330b0fd13da2..19c6a30300375def8c366cea2d1335f6f33b1c1f 100644 (file)
 
 package org.apache.poi.poifs.nio;
 
+import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 
+import org.apache.poi.util.IOUtils;
+
 /**
  * A POIFS {@link DataSource} backed by a File
  */
 public class FileBackedDataSource extends DataSource {
-   private FileChannel file;
-   public FileBackedDataSource(FileChannel file) {
-      this.file = file;
+   private FileChannel channel;
+   
+   public FileBackedDataSource(File file) throws FileNotFoundException {
+      if(!file.exists()) {
+         throw new FileNotFoundException(file.toString());
+      }
+      this.channel = (new RandomAccessFile(file, "r")).getChannel();
+   }
+   public FileBackedDataSource(FileChannel channel) {
+      this.channel = channel;
    }
    
    public void read(ByteBuffer dst, long position) throws IOException {
-      file.read(dst, position);
+      if(position >= size()) {
+         throw new IllegalArgumentException("Position " + position + " past the end of the file");
+      }
+      
+      channel.position(position);
+      int worked = IOUtils.readFully(channel, dst);
+      
+      if(worked == -1) {
+         throw new IllegalArgumentException("Position " + position + " past the end of the file");
+      }
    }
    
    public void write(ByteBuffer src, long position) throws IOException {
-      file.write(src, position);
+      channel.write(src, position);
    }
    
    public long size() throws IOException {
-      return file.size();
+      return channel.size();
    }
    
    public void close() throws IOException {
-      file.close();
+      channel.close();
    }
 }
index df039ee1da3ce87234a4b8ea72639838c3aab4ef..6eb0098cb6ea9805f62822e0493883591bc35d41 100644 (file)
 
 package org.apache.poi.poifs.nio;
 
-import java.io.IOException;
+import java.io.File;
+import java.nio.ByteBuffer;
+
+import org.apache.poi.POIDataSamples;
 
 import junit.framework.TestCase;
 
@@ -28,11 +31,141 @@ import junit.framework.TestCase;
  */
 public class TestDataSource extends TestCase
 {
-   public void testFile() throws IOException {
-      // TODO
+   private static POIDataSamples data = POIDataSamples.getPOIFSInstance();
+   
+   public void testFile() throws Exception {
+      File f = data.getFile("Notes.ole2");
+      
+      FileBackedDataSource ds = new FileBackedDataSource(f);
+      assertEquals(8192, ds.size());
+      
+      // Start of file
+      ByteBuffer bs = ByteBuffer.allocate(4); 
+      ds.read(bs, 0);
+      assertEquals(4, bs.capacity());
+      assertEquals(4, 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));
+      
+      // Mid way through
+      bs = ByteBuffer.allocate(8);
+      ds.read(bs, 0x400);
+      assertEquals(8, bs.capacity());
+      assertEquals(8, bs.position());
+      assertEquals((byte)'R', bs.get(0));
+      assertEquals(0, bs.get(1));
+      assertEquals((byte)'o', bs.get(2));
+      assertEquals(0, bs.get(3));
+      assertEquals((byte)'o', bs.get(4));
+      assertEquals(0, bs.get(5));
+      assertEquals((byte)'t', bs.get(6));
+      assertEquals(0, bs.get(7));
+      
+      // Can go to the end, but not past it
+      bs.clear();
+      ds.read(bs, 8190);
+      assertEquals(2, bs.position());
+      
+      // Can't go off the end
+      try {
+         bs.clear();
+         ds.read(bs, 8192);
+         fail("Shouldn't be able to read off the end of the file");
+      } catch(IllegalArgumentException e) {}
    }
    
-   public void testByteArray() throws IOException {
-      // TODO
+   public void testByteArray() throws Exception {
+      byte[] data = new byte[256];
+      byte b;
+      for(int i=0; i<data.length; i++) {
+         b = (byte)i;
+         data[i] = b;
+      }
+      
+      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));
+      
+      // 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));
+      
+      // 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));
+      
+      // 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));
+
+      // Past the end
+      bs.clear(); 
+      try {
+         ds.read(bs, 256);
+         fail("Shouldn't be able to read off the end");
+      } catch(IndexOutOfBoundsException e) {}
+      
+      
+      // Overwrite
+      bs.clear();
+      bs.put(0, (byte)-55);
+      bs.put(1, (byte)-54);
+      bs.put(2, (byte)-53);
+      bs.put(3, (byte)-52);
+      
+      ds.write(bs, 40);
+      bs.clear();
+      ds.read(bs, 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));
+      
+      // Append
+      bs.clear();
+      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, 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));
    }
 }