Return-Path: Delivered-To: apmail-poi-commits-archive@minotaur.apache.org Received: (qmail 5548 invoked from network); 19 Dec 2010 08:54:03 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 19 Dec 2010 08:54:03 -0000 Received: (qmail 20567 invoked by uid 500); 19 Dec 2010 08:54:03 -0000 Delivered-To: apmail-poi-commits-archive@poi.apache.org Received: (qmail 20541 invoked by uid 500); 19 Dec 2010 08:54:03 -0000 Mailing-List: contact commits-help@poi.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@poi.apache.org Delivered-To: mailing list commits@poi.apache.org Received: (qmail 20534 invoked by uid 99); 19 Dec 2010 08:54:02 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 19 Dec 2010 08:54:02 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 19 Dec 2010 08:53:58 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 101632388999; Sun, 19 Dec 2010 08:53:37 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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/ Date: Sun, 19 Dec 2010 08:53:36 -0000 To: commits@poi.apache.org From: nick@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101219085337.101632388999@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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