diff options
Diffstat (limited to 'base/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java')
| -rw-r--r-- | base/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/base/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java b/base/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java new file mode 100644 index 0000000..c229da1 --- /dev/null +++ b/base/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java @@ -0,0 +1,102 @@ +package bjc.utils.ioutils.blocks; + +import java.io.IOException; +import java.util.Deque; + +/** + * Provides a means of concatenating two block readers. + * + * @author bjculkin + * + */ +public class SerialBlockReader implements BlockReader { + private Deque<BlockReader> readerQueue; + + private int blockNo; + + /** + * Create a new serial block reader. + * + * @param readers + * The readers to pull from, in the order to pull from + * them. + */ + public SerialBlockReader(final BlockReader... readers) { + for (final BlockReader reader : readers) { + readerQueue.add(reader); + } + } + + @Override + public boolean hasNextBlock() { + if (readerQueue.isEmpty()) return false; + + /* + * Attempt to get a block from the first reader. + */ + boolean hasBlock = readerQueue.peek().hasNextBlock(); + boolean cont = hasBlock || readerQueue.isEmpty(); + + /* + * Close/dispose of readers until we get an open one. + */ + while (!cont) { + try { + readerQueue.pop().close(); + } catch (final IOException ioex) { + throw new IllegalStateException("Exception thrown by discarded reader", ioex); + } + + hasBlock = readerQueue.peek().hasNextBlock(); + cont = hasBlock || readerQueue.isEmpty(); + } + + return hasBlock; + } + + @Override + public Block getBlock() { + if (readerQueue.isEmpty()) + return null; + else return readerQueue.peek().getBlock(); + } + + @Override + public boolean nextBlock() { + if (readerQueue.isEmpty()) return false; + + boolean gotBlock = readerQueue.peek().nextBlock(); + boolean cont = gotBlock || readerQueue.isEmpty(); + + while (!cont) { + try { + readerQueue.pop().close(); + } catch (final IOException ioex) { + throw new IllegalStateException("Exception thrown by discarded reader", ioex); + } + + gotBlock = readerQueue.peek().nextBlock(); + cont = gotBlock || readerQueue.isEmpty(); + } + + if (cont) { + blockNo += 1; + } + + return cont; + } + + @Override + public int getBlockCount() { + return blockNo; + } + + @Override + public void close() throws IOException { + while (!readerQueue.isEmpty()) { + final BlockReader reader = readerQueue.pop(); + + reader.close(); + } + } +} |
