summaryrefslogtreecommitdiff
path: root/base/src/main/java/bjc/utils/ioutils
diff options
context:
space:
mode:
Diffstat (limited to 'base/src/main/java/bjc/utils/ioutils')
-rw-r--r--base/src/main/java/bjc/utils/ioutils/LevelSplitter.java274
-rw-r--r--base/src/main/java/bjc/utils/ioutils/MirrorDB.java26
-rw-r--r--base/src/main/java/bjc/utils/ioutils/ReportWriter.java270
-rw-r--r--base/src/main/java/bjc/utils/ioutils/blocks/Block.java61
-rw-r--r--base/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java3
5 files changed, 555 insertions, 79 deletions
diff --git a/base/src/main/java/bjc/utils/ioutils/LevelSplitter.java b/base/src/main/java/bjc/utils/ioutils/LevelSplitter.java
new file mode 100644
index 0000000..83b391b
--- /dev/null
+++ b/base/src/main/java/bjc/utils/ioutils/LevelSplitter.java
@@ -0,0 +1,274 @@
+package bjc.utils.ioutils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Splits a string on a delimiter, respecting grouping delimiters.
+ *
+ * By default, grouping delimiters are (), [], {}, and <>, as well as single and
+ * double quoted strings.
+ *
+ * @author bjculkin
+ *
+ */
+public class LevelSplitter {
+ /**
+ * Defaultly configured level splitter.
+ */
+ public final static LevelSplitter def = new LevelSplitter();
+
+ /**
+ * Check if a string contains any one of a specified number of things,
+ * respecting groups.
+ *
+ * @param haystack
+ * The string to look in.
+ * @param needles
+ * The strings to look for.
+ * @return Whether or not any of the strings were contained outside of
+ * groups.
+ */
+ public boolean levelContains(String haystack, String... needles) {
+ int nestLevel = 0;
+ int i = 0;
+
+ boolean prevCharWasSlash = false;
+ boolean inString = false;
+
+ char stringEnder = ' ';
+
+ while (i < haystack.length()) {
+ if (inString == false && nestLevel == 0) {
+ for (String needle : needles) {
+ if (haystack.regionMatches(i, needle, 0, needle.length())) {
+ return true;
+ }
+ }
+ }
+
+ if (inString) {
+ if (prevCharWasSlash == true) {
+ prevCharWasSlash = false;
+ } else if (haystack.charAt(i) == stringEnder) {
+ inString = false;
+ }
+ } else {
+ switch (haystack.charAt(i)) {
+ case '\'':
+ inString = true;
+ stringEnder = '\'';
+ break;
+ case '\"':
+ inString = true;
+ stringEnder = '\"';
+ break;
+ case '(':
+ case '[':
+ case '{':
+ case '<':
+ nestLevel += 1;
+ break;
+ case ')':
+ case ']':
+ case '}':
+ case '>':
+ nestLevel = Math.max(0, nestLevel - 1);
+ break;
+ }
+ }
+
+ i += 1;
+ }
+
+ return false;
+ }
+
+ /**
+ * Split a string, respecting groups.
+ *
+ * @param phrase
+ * The string to split.
+ * @param splits
+ * The strings to split on.
+ * @return A list of split strings. If keepDelims is true, it also
+ * includes the delimiters in between the split strings.
+ */
+ public List<String> levelSplit(String phrase, String... splits) {
+ return levelSplit(phrase, false, splits);
+ }
+
+ /**
+ * Split a string, respecting groups.
+ *
+ * @param phrase
+ * The string to split.
+ * @param keepDelims
+ * Whether or not to include the delimiters in the
+ * results.
+ * @param splits
+ * The strings to split on.
+ * @return A list of split strings. If keepDelims is true, it also
+ * includes the delimiters in between the split strings.
+ */
+ public List<String> levelSplit(String phrase, boolean keepDelims, String... splits) {
+ String work = phrase;
+
+ List<String> strangs = new ArrayList<>();
+
+ int nestLevel = 0;
+ int i = 0;
+
+ boolean prevCharWasSlash = false;
+ boolean inString = false;
+
+ char stringEnder = ' ';
+
+ // Shortcut empty strings
+ if (phrase.equals("")) {
+ strangs.add("");
+
+ return strangs;
+ }
+
+ while (i < work.length()) {
+ if (inString == false && nestLevel == 0) {
+ for (String split : splits) {
+ if (work.regionMatches(i, split, 0, split.length())) {
+ strangs.add(work.substring(0, i));
+
+ if (keepDelims) strangs.add(split);
+
+ work = work.substring(i + split.length());
+ i = 0;
+
+ continue;
+ }
+ }
+ }
+
+ if (inString) {
+ if (prevCharWasSlash == true) {
+ prevCharWasSlash = false;
+ } else if (work.charAt(i) == stringEnder) {
+ inString = false;
+ }
+ } else {
+ /*
+ * @TODO Ben Culkin 9/4/18
+ *
+ * This currently crashes if the string ends
+ * with one of the delimiters in question.
+ */
+ switch (work.charAt(i)) {
+ case '\'':
+ inString = true;
+ stringEnder = '\'';
+ break;
+ case '\"':
+ inString = true;
+ stringEnder = '\"';
+ break;
+ case '(':
+ case '[':
+ case '{':
+ case '<':
+ nestLevel += 1;
+ break;
+ case ')':
+ case ']':
+ case '}':
+ case '>':
+ nestLevel = Math.max(0, nestLevel - 1);
+ break;
+ }
+ }
+
+ i += 1;
+ }
+
+ strangs.add(work);
+
+ return strangs;
+ }
+
+ // @TODO @FIXME
+ //
+ // This doesn't seem like its working
+ @SuppressWarnings("javadoc")
+ public List<String> levelSplitRX(String phrase, String patt) {
+ return levelSplit(phrase, false, patt);
+ }
+
+ @SuppressWarnings("javadoc")
+ public List<String> levelSplitRX(String phrase, boolean keepDelims, String patt) {
+ Pattern pat = Pattern.compile(patt);
+
+ String work = phrase;
+ Matcher mat = pat.matcher(work);
+
+ List<String> strangs = new ArrayList<>();
+
+ int nestLevel = 0;
+ int i = 0;
+
+ boolean prevCharWasSlash = false;
+ boolean inString = false;
+
+ char stringEnder = ' ';
+
+ while (i < work.length()) {
+ if (inString == false && nestLevel == 0) {
+ if (mat.find(i)) {
+ strangs.add(work.substring(0, i));
+ if (keepDelims) strangs.add(mat.group());
+ work = work.substring(mat.end());
+ i = 0;
+
+ mat = pat.matcher(work);
+
+ continue;
+ }
+ }
+
+ if (inString) {
+ if (prevCharWasSlash == true) {
+ prevCharWasSlash = false;
+ } else if (work.charAt(i) == stringEnder) {
+ inString = false;
+ }
+ } else {
+ switch (work.charAt(i)) {
+ case '\'':
+ inString = true;
+ stringEnder = '\'';
+ break;
+ case '\"':
+ inString = true;
+ stringEnder = '\"';
+ break;
+ case '(':
+ case '[':
+ case '{':
+ case '<':
+ nestLevel += 1;
+ break;
+ case ')':
+ case ']':
+ case '}':
+ case '>':
+ nestLevel = Math.max(0, nestLevel - 1);
+ break;
+ }
+ }
+
+ i += 1;
+ }
+
+ strangs.add(work);
+
+ return strangs;
+ }
+}
diff --git a/base/src/main/java/bjc/utils/ioutils/MirrorDB.java b/base/src/main/java/bjc/utils/ioutils/MirrorDB.java
index 1f60059..1010fd6 100644
--- a/base/src/main/java/bjc/utils/ioutils/MirrorDB.java
+++ b/base/src/main/java/bjc/utils/ioutils/MirrorDB.java
@@ -1,8 +1,6 @@
package bjc.utils.ioutils;
import java.io.InputStream;
-import java.io.IOException;
-
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
@@ -12,9 +10,19 @@ import java.util.Scanner;
// What to do about one-to-many mirrored mappings?
//
// Currently, we pick the one with the latest codepoint
+
+/**
+ * A database for describing mirrored characters.
+ *
+ * @author bjculkin
+ *
+ */
public class MirrorDB {
private Map<String, String> mirrored;
+ /**
+ * Create a new database of mirrored characters.
+ */
public MirrorDB() {
mirrored = new HashMap<>();
@@ -47,10 +55,24 @@ public class MirrorDB {
}
}
+ /**
+ * Check if a string can be mirrored.
+ *
+ * @param mir
+ * The string to check for mirroring.
+ * @return Whether or not the given string can be mirrored.
+ */
public boolean canMirror(String mir) {
return mirrored.containsKey(mir);
}
+ /**
+ * Mirror a string.
+ *
+ * @param mir
+ * The string to mirror.
+ * @return The mirrored version of the string.
+ */
public String mirror(String mir) {
return mirrored.get(mir);
}
diff --git a/base/src/main/java/bjc/utils/ioutils/ReportWriter.java b/base/src/main/java/bjc/utils/ioutils/ReportWriter.java
index 647d4fe..4eb5aef 100644
--- a/base/src/main/java/bjc/utils/ioutils/ReportWriter.java
+++ b/base/src/main/java/bjc/utils/ioutils/ReportWriter.java
@@ -5,29 +5,46 @@ import java.io.Writer;
import bjc.utils.esodata.DefaultList;
+/**
+ * A writer with support for some formatting operations, such as autoindentation
+ * and pagination.
+ *
+ * @author bjculkin
+ *
+ */
public class ReportWriter extends Writer {
+ /*
+ * Storage of indentation values.
+ */
private static class IndentVal {
+ // # of character positions indentStr occupies
public int indentStrPos;
+ // String that is printed for the indent.
public String indentStr;
+ // Indent string w/ tabs replaced with spaces
public String indentStrSpacedTabs;
public IndentVal() {
}
}
+ // Writer to print to
private Writer contained;
- // # of character positions indentStr occupies
+ // Current indentation level
private int indentLevel;
+ // Current # of columns the indentation occupies
private int indentPos = 0;
+ // The indentation values to use
private DefaultList<IndentVal> iVals;
- private IndentVal defIVal;
+ // The default indentation value.
+ private IndentVal defIVal;
// # of char. positions to the tab
- private int tabEqv = 8;
- // @NOTE 9/17/19
+ private int tabEqv = 8;
+ // @NOTE 9/17/18
//
// Consider adding support for both the vertical tab, and variable tab
// stops.
@@ -35,86 +52,192 @@ public class ReportWriter extends Writer {
// For variable tab stops, decide between a set of numbers saying 'This
// level tab is counted as X spaces' and a set of numbers saying 'A tab
// advances to the next tab stop that has not been passed'
+
+ // The total count of lines printed
private int linesWritten = 0;
- private int linePos = 0;
+ // The current position in the line
+ private int linePos = 0;
+ // The number of newlines to print for every newline encountered.
private int lineSpacing = 1;
- private int pageLine = 0;
- private int pageNum = 0;
+ // The current line on the page
+ private int pageLine = 0;
+ // The current page number
+ private int pageNum = 0;
+ // The number of lines per page
private int linesPerPage = 20;
+ // Whether or not to print tabs as spaces.
private boolean printTabsAsSpaces;
+ // Whether or not the last character was a newline
private boolean lastCharWasNL;
- private char lastChar;
+ // The last character encountered
+ private char lastChar;
// Really wish java had public `readonly` properties. I wouldn't even
// care if that was a restriction that was only enforced by the compiler
+
+ /**
+ * Get the current indent level.
+ *
+ * @return The current indent level.
+ */
public int getLevel() {
return indentLevel;
}
+ /**
+ * Get the current line-spacing.
+ *
+ * This is the number of blank lines to print out every time a blank
+ * line is encountered in the input, and is set to 1 by default.
+ *
+ * @return The current line spacing.
+ */
public int getLineSpacing() {
return lineSpacing;
}
+ /**
+ * Get the current line on the page.
+ *
+ * @return The current line on the page.
+ */
public int getPageLine() {
return pageLine;
}
+ /**
+ * Get the current page number.
+ *
+ * @return The current page number.
+ */
public int getPageNum() {
return pageNum;
}
+ /**
+ * Get the number of lines per page.
+ *
+ * @return The number of lines per page.
+ */
public int getLinesPerPage() {
return linesPerPage;
}
+ /**
+ * Get the current indent position.
+ *
+ * This is the count of columns the indentation occupies.
+ *
+ * @return The current indent position.
+ */
public int getIndentPos() {
return indentPos;
}
+ /**
+ * Get the string of the default indentation value.
+ *
+ * @return The string for the default indentation value.
+ */
public String getString() {
return defIVal.indentStr;
}
+ /**
+ * Get the string of a specific indentation value.
+ *
+ * @param lvl
+ * The level to get the value for.
+ * @return The string for the specified indentation value.
+ */
public String getString(int lvl) {
return iVals.get(lvl).indentStr;
}
+ /**
+ * Get the number of spaces to a tab.
+ *
+ * @return The number of spaces to a tab.
+ */
public int getTabEqv() {
return tabEqv;
}
+ /**
+ * Get the total number of lines written.
+ *
+ * @return The total number of lines written.
+ */
public int getLinesWritter() {
return linesWritten;
}
+ /**
+ * Get the current position in the line.
+ *
+ * @return The current position in the line.
+ */
public int getLinePos() {
return linePos;
}
+ /**
+ * Get the last character printed.
+ *
+ * @return The last character printed.
+ */
public char getLastChar() {
return lastChar;
}
+ /**
+ * Get the contained writer.
+ *
+ * @return The contained writer.
+ */
public Writer getWriter() {
return contained;
}
+ /**
+ * Check if the last character was a newline.
+ *
+ * @return Was the last character a new line?
+ */
public boolean isLastCharNL() {
return lastCharWasNL;
}
+ /**
+ * Check if tabs are being printed as spaces.
+ *
+ * @return Are tabs being printed as spaces?
+ */
public boolean isPrintingTabsAsSpaces() {
return printTabsAsSpaces;
}
+ /**
+ * Set the line spacing.
+ *
+ * @param spacing
+ * The number of lines to print for every blank line
+ * encountered.
+ */
public void setLineSpacing(int spacing) {
lineSpacing = spacing;
}
+ /**
+ * Set whether tabs are being printed as spaces.
+ *
+ * @param tabsAsSpaces
+ * Whether to print tabs as spaces.
+ */
public void setPrintTabsAsSpaces(boolean tabsAsSpaces) {
printTabsAsSpaces = tabsAsSpaces;
@@ -122,6 +245,12 @@ public class ReportWriter extends Writer {
refreshIndents(-1);
}
+ /**
+ * Set the number of lines per page.
+ *
+ * @param lines
+ * The number of lines per page.
+ */
public void setLinesPerPage(int lines) {
linesPerPage = lines;
@@ -141,10 +270,22 @@ public class ReportWriter extends Writer {
}
}
+ /**
+ * Set the current indentation level.
+ *
+ * @param level
+ * The indentation level.
+ */
public void setLevel(int level) {
indentLevel = level;
}
+ /**
+ * Set the current amount of spaces per tab.
+ *
+ * @param eqv
+ * The amount of spaces per tab.
+ */
public void setTabEqv(int eqv) {
tabEqv = eqv;
@@ -157,12 +298,30 @@ public class ReportWriter extends Writer {
// Weirdness may occur if the indent string has a
// newline in it, since that newline won't be considered
// to exist by the IndentWriter
+
+ /**
+ * Set the default indentation string to use.
+ *
+ * NOTE: Using a string that contains a newline may cause weirdness of
+ * various sorts to happen.
+ *
+ * @param str
+ * The string to use for default indentation.
+ */
public void setString(String str) {
defIVal.indentStr = str;
refreshIndents(-2);
}
+ /**
+ * Set the indentation string for a specific indentation level.
+ *
+ * @param lvl
+ * The level to set the indentation string for.
+ * @param str
+ * The indentation string to use.
+ */
public void setString(int lvl, String str) {
iVals.get(lvl).indentStr = str;
@@ -174,6 +333,14 @@ public class ReportWriter extends Writer {
// Pass a index to refresh that level
// Pass -1 to refresh all indexes
// Pass -2 to refresh the default index
+ /**
+ * Refresh the indentation settings.
+ *
+ * @param lvl
+ * The level of indents to refresh. Passing a number >= 0
+ * refreshes that level, -1 refreshes every level, and -2
+ * refreshes just the default indentation.
+ */
private void refreshIndents(int lvl) {
if (lvl == -2) {
refreshIndent(defIVal);
@@ -181,21 +348,24 @@ public class ReportWriter extends Writer {
for (IndentVal ival : iVals) {
refreshIndent(ival);
}
+
+ refreshIndent(defIVal);
} else {
refreshIndent(iVals.get(lvl));
}
}
+ // Refresh an indent val to respect current settings
private void refreshIndent(IndentVal vl) {
vl.indentStrPos = 0;
int indentLength = vl.indentStr.length();
StringBuilder conv = new StringBuilder();
- for(int i = 0; i < indentLength; i++) {
+ for (int i = 0; i < indentLength; i++) {
char c = vl.indentStr.charAt(i);
- if(c == '\t') {
- for(int j = 0; j < tabEqv; j++) {
+ if (c == '\t') {
+ for (int j = 0; j < tabEqv; j++) {
conv.append(' ');
}
@@ -209,25 +379,30 @@ public class ReportWriter extends Writer {
vl.indentStrSpacedTabs = conv.toString();
}
+ /**
+ * Duplicate this writers settings.
+ * @param contents The internal writer to use.
+ * @return A new writer, sharing this ones settings, but writing to the provided Writer instead.
+ */
public ReportWriter duplicate(Writer contents) {
ReportWriter rw = new ReportWriter(contents);
- rw.iVals = iVals;
- rw.defIVal = defIVal;
+ rw.iVals = iVals;
+ rw.defIVal = defIVal;
rw.indentLevel = indentLevel;
- rw.indentPos = indentPos;
+ rw.indentPos = indentPos;
rw.tabEqv = tabEqv;
rw.linesWritten = linesWritten;
- rw.linePos = linePos;
- rw.lineSpacing = lineSpacing;
+ rw.linePos = linePos;
+ rw.lineSpacing = lineSpacing;
rw.printTabsAsSpaces = printTabsAsSpaces;
- rw.pageLine = pageLine;
- rw.pageNum = pageNum;
+ rw.pageLine = pageLine;
+ rw.pageNum = pageNum;
rw.linesPerPage = linesPerPage;
// @NOTE 9/5/18
@@ -238,10 +413,20 @@ public class ReportWriter extends Writer {
return rw;
}
+ /**
+ * Create a new ReportWriter.
+ * @param write The place to write to.
+ */
public ReportWriter(Writer write) {
this(write, 0, "\t");
}
+ /**
+ * Create a new ReportWriter with the specified default indentation values.
+ * @param write The place to write to.
+ * @param level The current indentation level.
+ * @param indentStr The indentation string.
+ */
public ReportWriter(Writer write, int level, String indentStr) {
super();
@@ -250,19 +435,30 @@ public class ReportWriter extends Writer {
indentLevel = level;
defIVal = new IndentVal();
- iVals = new DefaultList<>(defIVal);
+ iVals = new DefaultList<>(defIVal);
setString(indentStr);
}
+ /**
+ * Indent a specific number of levels.
+ * @param lvl The number of levels to indent.
+ */
public void indent(int lvl) {
indentLevel += lvl;
}
+ /**
+ * Indent one level.
+ */
public void indent() {
indent(1);
}
+ /**
+ * Dedent a specific number of levels.
+ * @param lvl The number of levels to dedent.
+ */
public void dedent(int lvl) {
// @NOTE 9/5/18
//
@@ -271,10 +467,18 @@ public class ReportWriter extends Writer {
indentLevel = Math.max(0, indentLevel - lvl);
}
+ /**
+ * Dedent 1 level.
+ */
public void dedent() {
dedent(1);
}
+ /**
+ * Writes a buffer to the output, then clears it.
+ * @param sb The buffer to write and clear.
+ * @throws IOException If something goes wrong writing the buffer.
+ */
public void writeBuffer(StringBuffer sb) throws IOException {
write(sb.toString());
@@ -289,14 +493,14 @@ public class ReportWriter extends Writer {
// next page, or just printing the actual form-feed and hoping whatever
// reading software handles it properly
private void writePage() {
- pageNum += 1;
+ pageNum += 1;
pageLine -= linesPerPage;
}
private void writeNL(char c) throws IOException {
// Count lines written
linesWritten += lineSpacing;
- pageLine += lineSpacing;
+ pageLine += lineSpacing;
lastCharWasNL = true;
@@ -317,41 +521,40 @@ public class ReportWriter extends Writer {
writePage();
}
-
- linePos = 0;
+ linePos = 0;
indentPos = 0;
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
// Skip empty writes
- if(len == 0) return;
+ if (len == 0) return;
// Last character was a new line, print the indent string
- if(lastCharWasNL) {
+ if (lastCharWasNL) {
lastCharWasNL = false;
printIndents();
}
- for(int i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++) {
int idx = i + off;
char c = cbuf[idx];
- if(c == '\n' || c == '\r' || (c == '\n' && lastChar != '\r') || c == '\f') {
+ if ((c == '\n' && lastChar != '\r') || c == '\n' || c == '\r' || c == '\f') {
writeNL(c);
} else {
- if(lastCharWasNL) {
+ if (lastCharWasNL) {
lastCharWasNL = false;
printIndents();
}
- if(c == '\t') {
+ if (c == '\t') {
linePos += tabEqv;
- for(int j = 0; j < tabEqv; j++) {
+ for (int j = 0; j < tabEqv; j++) {
contained.write(' ');
}
} else {
@@ -368,10 +571,11 @@ public class ReportWriter extends Writer {
for (int j = 0; j < indentLevel; j++) {
IndentVal ival = iVals.get(j);
- if (printTabsAsSpaces) contained.write(ival.indentStrSpacedTabs);
- else contained.write(ival.indentStr);
+ if (printTabsAsSpaces)
+ contained.write(ival.indentStrSpacedTabs);
+ else contained.write(ival.indentStr);
- linePos += ival.indentStrPos;
+ linePos += ival.indentStrPos;
indentPos += ival.indentStrPos;
}
}
diff --git a/base/src/main/java/bjc/utils/ioutils/blocks/Block.java b/base/src/main/java/bjc/utils/ioutils/blocks/Block.java
index 61d473c..bf0257e 100644
--- a/base/src/main/java/bjc/utils/ioutils/blocks/Block.java
+++ b/base/src/main/java/bjc/utils/ioutils/blocks/Block.java
@@ -27,19 +27,26 @@ public class Block {
*/
public final int blockNo;
+ /**
+ * The line offset number for this block.
+ *
+ * Essentially, this is the absolute number of lines that this block is
+ * into whatever source it came from, where as startLine and endLine are
+ * relative to the BlockReader this Block is from.
+ */
public int lineOffset;
/**
* Create a new block.
*
* @param blockNo
- * The number of this block.
+ * The number of this block.
* @param contents
- * The contents of this block.
+ * The contents of this block.
* @param startLine
- * The line this block started on.
+ * The line this block started on.
* @param endLine
- * The line this block ended.
+ * The line this block ended.
*/
public Block(final int blockNo, final String contents, final int startLine, final int endLine) {
this.contents = contents;
@@ -49,50 +56,16 @@ public class Block {
}
@Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
-
- result = prime * result + blockNo;
- result = prime * result + (contents == null ? 0 : contents.hashCode());
- result = prime * result + endLine;
- result = prime * result + startLine;
-
- return result;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if(this == obj) return true;
- if(obj == null) return false;
- if(!(obj instanceof Block)) return false;
-
- final Block other = (Block) obj;
-
- if(blockNo != other.blockNo) return false;
-
- if(contents == null) {
- if(other.contents != null) return false;
- } else if(!contents.equals(other.contents)) return false;
-
- if(endLine != other.endLine) return false;
- if(startLine != other.startLine) return false;
-
- return true;
- }
-
- @Override
public String toString() {
- if(lineOffset != -1) {
+ if (lineOffset != -1) {
String fmt = "Block #%d (from lines %d (%d) to %d (%d)), length: %d characters";
- return String.format(fmt, blockNo, startLine + lineOffset,
- startLine, endLine + lineOffset,
+ return String.format(fmt, blockNo, startLine + lineOffset, startLine, endLine + lineOffset,
endLine + lineOffset, contents.length());
- } else {
- String fmt = "Block #%d (from lines %d to %d), length: %d characters";
-
- return String.format(fmt, 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());
}
}
diff --git a/base/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java b/base/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java
index 02483c1..66ebd66 100644
--- a/base/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java
+++ b/base/src/main/java/bjc/utils/ioutils/blocks/SerialBlockReader.java
@@ -2,6 +2,7 @@ package bjc.utils.ioutils.blocks;
import java.io.IOException;
import java.util.Deque;
+import java.util.LinkedList;
/**
* Provides a means of concatenating two block readers.
@@ -21,6 +22,8 @@ public class SerialBlockReader implements BlockReader {
* The readers to pull from, in the order to pull from them.
*/
public SerialBlockReader(final BlockReader... readers) {
+ readerQueue = new LinkedList<>();
+
for(final BlockReader reader : readers) {
readerQueue.add(reader);
}