From d766896972c9e9be4a9e0021ec5f4f0665901865 Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Sat, 9 Sep 2017 21:46:16 -0300 Subject: Update Most of it is documentation changes. The rest is more work on BlockReaders, as well as a simple command language for configuring them. --- .../main/java/bjc/utils/ioutils/blocks/Block.java | 7 +- .../java/bjc/utils/ioutils/blocks/BlockReader.java | 26 +++--- .../utils/ioutils/blocks/FilteredBlockReader.java | 97 ++++++++++++++++++++++ .../utils/ioutils/blocks/LayeredBlockReader.java | 17 +++- .../utils/ioutils/blocks/MappedBlockReader.java | 44 ++++++++++ .../utils/ioutils/blocks/PushbackBlockReader.java | 8 +- .../utils/ioutils/blocks/SerialBlockReader.java | 12 +-- .../utils/ioutils/blocks/SimpleBlockReader.java | 15 +++- .../utils/ioutils/blocks/TriggeredBlockReader.java | 5 +- 9 files changed, 202 insertions(+), 29 deletions(-) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/FilteredBlockReader.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/MappedBlockReader.java (limited to 'BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks') diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/Block.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/Block.java index b514d17..15f3510 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/Block.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/Block.java @@ -81,7 +81,8 @@ public class Block { @Override public String toString() { - return String.format("Block #%d (from lines %d to %d), length: %d characters", blockNo, startLine, - endLine, contents.length()); + String fmt = "Block #%d (from lines %d to %d), length: %d characters"; + + return String.format(fmt, blockNo, startLine, endLine, contents.length()); } -} \ No newline at end of file +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/BlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/BlockReader.java index dac535e..3c695c6 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/BlockReader.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/BlockReader.java @@ -33,6 +33,20 @@ public interface BlockReader extends AutoCloseable, Iterator { */ boolean nextBlock(); + /** + * Retrieve the number of blocks that have been read so far. + * + * @return The number of blocks read so far. + */ + int getBlockCount(); + + @Override + void close() throws IOException; + + /* + * Methods with default impls. + */ + /** * Execute an action for each remaining block. * @@ -45,16 +59,6 @@ public interface BlockReader extends AutoCloseable, Iterator { } } - /** - * Retrieve the number of blocks that have been read so far. - * - * @return The number of blocks read so far. - */ - int getBlockCount(); - - @Override - void close() throws IOException; - @Override default boolean hasNext() { return hasNextBlock(); @@ -66,4 +70,4 @@ public interface BlockReader extends AutoCloseable, Iterator { return getBlock(); } -} \ No newline at end of file +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/FilteredBlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/FilteredBlockReader.java new file mode 100644 index 0000000..a9e5923 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/FilteredBlockReader.java @@ -0,0 +1,97 @@ +package bjc.utils.ioutils.blocks; + +import java.io.IOException; + +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class FilteredBlockReader implements BlockReader { + /* + * The source of blocks. + */ + private BlockReader source; + + /* + * The current and next block. + * + * Both have already been checked for the predicate. + */ + private Block current; + private Block pending; + + /* + * Number of blocks that passed the predicate. + */ + private int passed; + + /* + * The predicate blocks must pass. + */ + private Predicate pred; + + /* + * The action to call on failure, if there is one. + */ + private Consumer failAction; + + public FilteredBlockReader(BlockReader src, Predicate predic) { + this(src, predic, null); + } + + public FilteredBlockReader(BlockReader src, Predicate predic, Consumer failAct) { + source = src; + pred = predic; + failAction = failAct; + + passed = 0; + } + + @Override + public boolean hasNextBlock() { + if(pending != null) return true; + + while(source.hasNextBlock()) { + /* + * Only say we have a next block if the next block would + * pass the predicate. + */ + pending = source.next(); + + if(pred.test(pending)) { + passed += 1; + return true; + } else { + failAction.accept(pending); + } + } + + return false; + } + + @Override + public Block getBlock() { + return current; + } + + @Override + public boolean nextBlock() { + if(pending != null || hasNextBlock()) { + current = pending; + pending = null; + + return true; + } + + return false; + } + + @Override + public int getBlockCount() { + return passed; + } + + @Override + public void close() throws IOException { + source.close(); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/LayeredBlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/LayeredBlockReader.java index 54010fe..967a1f2 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/LayeredBlockReader.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/LayeredBlockReader.java @@ -14,9 +14,15 @@ import java.io.IOException; * */ public class LayeredBlockReader implements BlockReader { - private final BlockReader first; - private final BlockReader second; + /* + * The readers to drain from. + */ + private final BlockReader first; + private final BlockReader second; + /* + * The current block number. + */ private int blockNo; /** @@ -42,13 +48,16 @@ public class LayeredBlockReader implements BlockReader { public Block getBlock() { final Block firstBlock = first.getBlock(); + /* + * Only drain a block from the second reader if none are + * available in the first reader. + */ return firstBlock == null ? second.getBlock() : firstBlock; } @Override public boolean nextBlock() { final boolean gotFirst = first.nextBlock(); - final boolean succ = gotFirst ? gotFirst : second.nextBlock(); if (succ) { @@ -69,4 +78,4 @@ public class LayeredBlockReader implements BlockReader { first.close(); } -} \ No newline at end of file +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/MappedBlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/MappedBlockReader.java new file mode 100644 index 0000000..1996421 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/MappedBlockReader.java @@ -0,0 +1,44 @@ +package bjc.utils.ioutils.blocks; + +import java.io.IOException; + +import java.util.function.UnaryOperator; + +public class MappedBlockReader implements BlockReader { + private BlockReader reader; + + private Block current; + + private UnaryOperator transform; + + public MappedBlockReader(BlockReader source, UnaryOperator trans) { + reader = source; + transform = trans; + } + + @Override + public boolean hasNextBlock() { + return reader.hasNextBlock(); + } + + @Override + public Block getBlock() { + return current; + } + + @Override + public boolean nextBlock() { + if(hasNextBlock()) { + current = trans.apply(reader.next()); + + return true; + } + + return false; + } + + @Override + public int getBlockCount() { + return reader.getBlockCount(); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/PushbackBlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/PushbackBlockReader.java index d7ba247..0cc9dea 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/PushbackBlockReader.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/PushbackBlockReader.java @@ -14,6 +14,9 @@ import java.util.LinkedList; public class PushbackBlockReader implements BlockReader { private final BlockReader source; + /* + * The queue of pushed-back blocks. + */ private final Deque waiting; private Block curBlock; @@ -44,6 +47,9 @@ public class PushbackBlockReader implements BlockReader { @Override public boolean nextBlock() { + /* + * Drain pushed-back blocks first. + */ if (!waiting.isEmpty()) { curBlock = waiting.pop(); @@ -97,4 +103,4 @@ public class PushbackBlockReader implements BlockReader { return String.format("PushbackBlockReader [waiting=%s, curBlock=%s, blockNo=%s]", waiting, curBlock, blockNo); } -} \ No newline at end of file +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java index 7735981..c229da1 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java @@ -31,10 +31,15 @@ public class SerialBlockReader implements BlockReader { 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(); @@ -43,7 +48,6 @@ public class SerialBlockReader implements BlockReader { } hasBlock = readerQueue.peek().hasNextBlock(); - cont = hasBlock || readerQueue.isEmpty(); } @@ -62,7 +66,6 @@ public class SerialBlockReader implements BlockReader { if (readerQueue.isEmpty()) return false; boolean gotBlock = readerQueue.peek().nextBlock(); - boolean cont = gotBlock || readerQueue.isEmpty(); while (!cont) { @@ -73,7 +76,6 @@ public class SerialBlockReader implements BlockReader { } gotBlock = readerQueue.peek().nextBlock(); - cont = gotBlock || readerQueue.isEmpty(); } @@ -97,4 +99,4 @@ public class SerialBlockReader implements BlockReader { reader.close(); } } -} \ No newline at end of file +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/SimpleBlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/SimpleBlockReader.java index ca04d8f..734bde8 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/SimpleBlockReader.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/SimpleBlockReader.java @@ -21,14 +21,18 @@ public class SimpleBlockReader implements BlockReader { /* * I/O source for blocks. */ - private final Scanner blockReader; + private final Scanner blockReader; /* * The current block. */ - private Block currBlock; - private int blockNo; - private int lineNo; + private Block currBlock; + + /* + * Info about the current block. + */ + private int blockNo; + private int lineNo; /** * Create a new block reader. @@ -64,6 +68,9 @@ public class SimpleBlockReader implements BlockReader { @Override public boolean nextBlock() { try { + /* + * Read in a new block, and keep the line numbers sane. + */ final int blockStartLine = lineNo; final String blockContents = blockReader.next(); final int blockEndLine = lineNo + StringUtils.countMatches(blockContents, "\\R"); diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/TriggeredBlockReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/TriggeredBlockReader.java index 0e50ad6..74076bb 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/TriggeredBlockReader.java +++ b/BJC-Utils2/src/main/java/bjc/utils/ioutils/blocks/TriggeredBlockReader.java @@ -11,6 +11,9 @@ import java.io.IOException; public class TriggeredBlockReader implements BlockReader { private final BlockReader source; + /* + * The action to fire. + */ private final Runnable action; /** @@ -59,4 +62,4 @@ public class TriggeredBlockReader implements BlockReader { public String toString() { return String.format("TriggeredBlockReader [source=%s]", source); } -} \ No newline at end of file +} -- cgit v1.2.3