Tests and tweaks to the NIO DataSource code

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1050758 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2010-12-19 04:59:49 +00:00
parent c0e28795c1
commit 4b8e5f61c1
3 changed files with 170 additions and 14 deletions

View File

@ -32,13 +32,15 @@ public class ByteArrayBackedDataSource extends DataSource {
} }
public void read(ByteBuffer dst, long position) { public void read(ByteBuffer dst, long position) {
if(position + dst.capacity() > size) { if(position >= size) {
throw new IndexOutOfBoundsException( throw new IndexOutOfBoundsException(
"Unable to read " + dst.capacity() + " bytes from " + "Unable to read " + dst.capacity() + " bytes from " +
position + " in stream of length " + size 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) { public void write(ByteBuffer src, long position) {

View File

@ -17,32 +17,53 @@
package org.apache.poi.poifs.nio; package org.apache.poi.poifs.nio;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import org.apache.poi.util.IOUtils;
/** /**
* A POIFS {@link DataSource} backed by a File * A POIFS {@link DataSource} backed by a File
*/ */
public class FileBackedDataSource extends DataSource { public class FileBackedDataSource extends DataSource {
private FileChannel file; private FileChannel channel;
public FileBackedDataSource(FileChannel file) {
this.file = file; 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 { 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 { public void write(ByteBuffer src, long position) throws IOException {
file.write(src, position); channel.write(src, position);
} }
public long size() throws IOException { public long size() throws IOException {
return file.size(); return channel.size();
} }
public void close() throws IOException { public void close() throws IOException {
file.close(); channel.close();
} }
} }

View File

@ -19,7 +19,10 @@
package org.apache.poi.poifs.nio; 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; import junit.framework.TestCase;
@ -28,11 +31,141 @@ import junit.framework.TestCase;
*/ */
public class TestDataSource extends TestCase public class TestDataSource extends TestCase
{ {
public void testFile() throws IOException { private static POIDataSamples data = POIDataSamples.getPOIFSInstance();
// TODO
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 { public void testByteArray() throws Exception {
// TODO 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));
} }
} }