This is implemented as a writer because there can be several output characters for a single character. I could not imagine it as a reader. Quite a difficult task, but quite expandable.
String multilineJson = "{\n" + "prop1 = \"value1\",\n" + "prop2 = \"multi line\n" + "value2\"\n" + "}\n"; String multilineJsonExpected = "{\n" + "prop1 = \"value1\",\n" + "prop2 = \"multi line\\nvalue2\"\n" + "}\n"; StringWriter sw = new StringWriter(); JsonProcessor jsonProcessor = new JsonProcessor(sw); jsonProcessor.write(multilineJson); assertEquals(multilineJsonExpected, sw.toString());
Implementation
public class JsonProcessor extends FilterWriter { private char[] curr; private int currIdx; private boolean doubleQuoted; public JsonProcessor(Writer out) { super(out); } @Override public void write(String str) throws IOException { char[] arr = str.toCharArray(); write(arr, 0, arr.length); } @Override synchronized public void write(char[] cbuf, int off, int len) throws IOException { curr = Arrays.copyOfRange(cbuf, off, len - off); for (currIdx = 0; currIdx < curr.length; currIdx++) { processChar(); } } private void processChar() throws IOException { switch (currentChar()) { case '"': processDoubleQuotesSymbol(); break; case '\n': case '\r': processLineBreakSymbol(); break; default: write(currentChar()); break; } } private void processDoubleQuotesSymbol() throws IOException { doubleQuoted = !doubleQuoted; write('"'); } private void processLineBreakSymbol() throws IOException { if (doubleQuoted) { write('\\'); write('n'); if (lookAhead() == '\n' || lookAhead() == '\r') { currIdx++; } } else { write(currentChar()); } } private char currentChar() { return curr[currIdx]; } private char lookAhead() { if (currIdx >= curr.length) { return 0; } return curr[currIdx + 1]; } }
Mykhaylo Adamovych Jun 15 '16 at 13:51 2016-06-15 13:51
source share