mirror of https://github.com/apache/poi.git
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:
parent
c0e28795c1
commit
4b8e5f61c1
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue