package er.woinstaller.io; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public class MultiBlockInputStream extends InputStream { private final InputStream _inputSource; private final List<BlockEntry> _blockList; private InputStream _delegate; private int _blockPosition = 0; private BlockEntry _currentBlock = null; public MultiBlockInputStream(InputStream input, List<BlockEntry> blockList) { _inputSource = input; List<BlockEntry> newList = new ArrayList<BlockEntry>(); newList.addAll(blockList); _blockList = newList; } @Override public int read() throws IOException { if (_delegate == null) { _delegate = getNextDelegate(); } if (_delegate == null) { return -1; } int result = _delegate.read(); if (result == -1) { _delegate = getNextDelegate(); if (_delegate != null) { return _delegate.read(); } } return result; } @Override public int read(byte[] b, int off, int len) throws IOException { if (_delegate == null) { _delegate = getNextDelegate(); } if (_delegate == null) { return -1; } int result = 0; while (result < len) { result = _delegate.read(b, off, len); if (result < len) { int result2 = _delegate.read(b, off+result, len-result); if (result2 != -1) { result += result2; } else { _delegate = getNextDelegate(); if (_delegate == null) { return result; } } } } return result; } private InputStream getNextDelegate() throws IOException { if (_delegate != null) { _delegate = null; _blockPosition++; } if (_blockList.size() > _blockPosition) { BlockEntry newBlock = _blockList.get(_blockPosition); long newOffset = newBlock.offset; if (_currentBlock != null && _currentBlock != newBlock) { newOffset -= (_currentBlock.offset + _currentBlock.length); } _currentBlock = newBlock; _delegate = new BoundedInputStream(_inputSource, newOffset, newBlock.length); } return _delegate; } }