Index: poi/poi/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- poi/poi/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java (revision cee9eb7e2b487c4b451bd167e07e6309835a943b) +++ poi/poi/src/java/org/apache/poi/poifs/filesystem/POIFSMiniStore.java (date 1615423514626) @@ -64,20 +64,25 @@ int bigBlockOffset = byteOffset % _filesystem.getBigBlockSize(); // Now locate the data block for it - Iterator it = _mini_stream.getBlockIterator(); + Iterator it = _mini_stream.getBlockOffsetIterator(); for(int i=0; iUTF-8 =================================================================== --- poi/poi/src/java/org/apache/poi/poifs/filesystem/POIFSStream.java (revision cee9eb7e2b487c4b451bd167e07e6309835a943b) +++ poi/poi/src/java/org/apache/poi/poifs/filesystem/POIFSStream.java (date 1615264885529) @@ -96,6 +96,15 @@ return new StreamBlockByteBufferIterator(startBlock); } + Iterator 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 @@ /** * Class that handles a streaming read of one stream */ - private class StreamBlockByteBufferIterator implements Iterator { + private class StreamBlockOffsetIterator implements Iterator { private final ChainLoopDetector loopDetector; private int nextBlock; - StreamBlockByteBufferIterator(int firstBlock) { + StreamBlockOffsetIterator(int firstBlock) { this.nextBlock = firstBlock; try { this.loopDetector = blockStore.getChainLoopDetector(); @@ -157,26 +166,54 @@ 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() { + throw new UnsupportedOperationException(); + } + } + + /** + * Class that handles a streaming read of one stream + */ + private class StreamBlockByteBufferIterator implements Iterator { + 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(); - } - } + public void remove() { + throw new UnsupportedOperationException(); + } + } + protected class StreamBlockByteBuffer extends OutputStream { byte[] oneByte = new byte[1]; ByteBuffer buffer;