aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java25
-rw-r--r--src/java/org/apache/poi/poifs/filesystem/POIFSStream.java59
2 files changed, 63 insertions, 21 deletions
diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java b/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java
index 701dad68a4..623bd99467 100644
--- a/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java
+++ b/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java
@@ -61,20 +61,25 @@ public class POIFSMiniStore extends BlockStore {
int bigBlockOffset = byteOffset % _filesystem.getBigBlockSize();
// Now locate the data block for it
- Iterator<ByteBuffer> it = _mini_stream.getBlockIterator();
+ Iterator<Integer> it = _mini_stream.getBlockOffsetIterator();
for (int i = 0; i < bigBlockNumber; i++) {
it.next();
}
- ByteBuffer dataBlock = it.next();
- assert (dataBlock != null);
- // Position ourselves, and take a slice
- dataBlock.position(
- dataBlock.position() + bigBlockOffset
- );
- ByteBuffer miniBuffer = dataBlock.slice();
- miniBuffer.limit(POIFSConstants.SMALL_BLOCK_SIZE);
- return miniBuffer;
+ try {
+ ByteBuffer dataBlock = _filesystem.getBlockAt(it.next());
+ assert(dataBlock != null);
+
+ // Position ourselves, and take a slice
+ dataBlock.position(
+ dataBlock.position() + bigBlockOffset
+ );
+ ByteBuffer miniBuffer = dataBlock.slice();
+ miniBuffer.limit(POIFSConstants.SMALL_BLOCK_SIZE);
+ return miniBuffer;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
/**
diff --git a/src/java/org/apache/poi/poifs/filesystem/POIFSStream.java b/src/java/org/apache/poi/poifs/filesystem/POIFSStream.java
index 356b78c9f7..8d8f7c575d 100644
--- a/src/java/org/apache/poi/poifs/filesystem/POIFSStream.java
+++ b/src/java/org/apache/poi/poifs/filesystem/POIFSStream.java
@@ -96,6 +96,15 @@ public class POIFSStream implements Iterable<ByteBuffer>
return new StreamBlockByteBufferIterator(startBlock);
}
+ Iterator<Integer> getBlockOffsetIterator() {
+ if(startBlock == POIFSConstants.END_OF_CHAIN) {
+ throw new IllegalStateException(
+ "Can't read from a new stream before it has been written to"
+ );
+ }
+ return new StreamBlockOffsetIterator(startBlock);
+ }
+
/**
* Updates the contents of the stream to the new
* set of bytes.
@@ -140,11 +149,11 @@ public class POIFSStream implements Iterable<ByteBuffer>
/**
* Class that handles a streaming read of one stream
*/
- private class StreamBlockByteBufferIterator implements Iterator<ByteBuffer> {
+ private class StreamBlockOffsetIterator implements Iterator<Integer> {
private final ChainLoopDetector loopDetector;
private int nextBlock;
- StreamBlockByteBufferIterator(int firstBlock) {
+ StreamBlockOffsetIterator(int firstBlock) {
this.nextBlock = firstBlock;
try {
this.loopDetector = blockStore.getChainLoopDetector();
@@ -157,19 +166,15 @@ public class POIFSStream implements Iterable<ByteBuffer>
return nextBlock != POIFSConstants.END_OF_CHAIN;
}
- public ByteBuffer next() {
+ public Integer next() {
if (!hasNext()) {
throw new NoSuchElementException("Can't read past the end of the stream");
}
- try {
- loopDetector.claim(nextBlock);
- ByteBuffer data = blockStore.getBlockAt(nextBlock);
- nextBlock = blockStore.getNextBlock(nextBlock);
- return data;
- } catch(IOException e) {
- throw new RuntimeException(e);
- }
+ loopDetector.claim(nextBlock);
+ int currentBlock = nextBlock;
+ nextBlock = blockStore.getNextBlock(nextBlock);
+ return currentBlock;
}
public void remove() {
@@ -177,6 +182,38 @@ public class POIFSStream implements Iterable<ByteBuffer>
}
}
+ /**
+ * Class that handles a streaming read of one stream
+ */
+ private class StreamBlockByteBufferIterator implements Iterator<ByteBuffer> {
+ private final StreamBlockOffsetIterator offsetIterator;
+
+ StreamBlockByteBufferIterator(int firstBlock) {
+ offsetIterator = new StreamBlockOffsetIterator(firstBlock);
+ }
+
+ public boolean hasNext() {
+ return offsetIterator.hasNext();
+ }
+
+ public ByteBuffer next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException("Can't read past the end of the stream");
+ }
+
+ try {
+ return blockStore.getBlockAt(offsetIterator.next());
+ } catch(IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+
protected class StreamBlockByteBuffer extends OutputStream {
byte[] oneByte = new byte[1];
ByteBuffer buffer;