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