1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.util; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.io.IOException; 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.io.OutputStream; 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.io.OutputStreamWriter; 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.io.StringWriter; 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.io.Writer; 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Class that takes a combined output destination and provides two 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * output writers, one of which ends up writing to the left column and 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * one which goes on the right. 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class TwoColumnOutput { 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} underlying writer for final output */ 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final Writer out; 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code > 0;} the left column width */ 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int leftWidth; 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} pending left column output */ 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final StringBuffer leftBuf; 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} pending right column output */ 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final StringBuffer rightBuf; 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} left column writer */ 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final IndentingWriter leftColumn; 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} right column writer */ 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final IndentingWriter rightColumn; 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Turns the given two strings (with widths) and spacer into a formatted 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * two-column string. 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param s1 {@code non-null;} first string 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param width1 {@code > 0;} width of the first column 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param spacer {@code non-null;} spacer string 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param s2 {@code non-null;} second string 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param width2 {@code > 0;} width of the second column 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} an appropriately-formatted string 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static String toString(String s1, int width1, String spacer, 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul String s2, int width2) { 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int len1 = s1.length(); 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int len2 = s2.length(); 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul StringWriter sw = new StringWriter((len1 + len2) * 3); 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul TwoColumnOutput twoOut = 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul new TwoColumnOutput(sw, width1, width2, spacer); 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul try { 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul twoOut.getLeft().write(s1); 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul twoOut.getRight().write(s2); 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } catch (IOException ex) { 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new RuntimeException("shouldn't happen", ex); 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul twoOut.flush(); 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return sw.toString(); 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param out {@code non-null;} writer to send final output to 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param leftWidth {@code > 0;} width of the left column, in characters 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param rightWidth {@code > 0;} width of the right column, in characters 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param spacer {@code non-null;} spacer string to sit between the two columns 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public TwoColumnOutput(Writer out, int leftWidth, int rightWidth, 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul String spacer) { 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (out == null) { 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("out == null"); 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (leftWidth < 1) { 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("leftWidth < 1"); 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (rightWidth < 1) { 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("rightWidth < 1"); 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (spacer == null) { 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("spacer == null"); 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul StringWriter leftWriter = new StringWriter(1000); 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul StringWriter rightWriter = new StringWriter(1000); 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.out = out; 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.leftWidth = leftWidth; 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.leftBuf = leftWriter.getBuffer(); 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.rightBuf = rightWriter.getBuffer(); 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.leftColumn = new IndentingWriter(leftWriter, leftWidth); 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.rightColumn = 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul new IndentingWriter(rightWriter, rightWidth, spacer); 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param out {@code non-null;} stream to send final output to 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param leftWidth {@code >= 1;} width of the left column, in characters 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param rightWidth {@code >= 1;} width of the right column, in characters 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param spacer {@code non-null;} spacer string to sit between the two columns 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public TwoColumnOutput(OutputStream out, int leftWidth, int rightWidth, 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul String spacer) { 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this(new OutputStreamWriter(out), leftWidth, rightWidth, spacer); 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the writer to use to write to the left column. 133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the left column writer 135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Writer getLeft() { 137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return leftColumn; 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the writer to use to write to the right column. 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the right column writer 144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Writer getRight() { 146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return rightColumn; 147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Flushes the output. If there are more lines of pending output in one 151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * column, then the other column will get filled with blank lines. 152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void flush() { 154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul try { 155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul appendNewlineIfNecessary(leftBuf, leftColumn); 156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul appendNewlineIfNecessary(rightBuf, rightColumn); 157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul outputFullLines(); 158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul flushLeft(); 159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul flushRight(); 160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } catch (IOException ex) { 161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new RuntimeException(ex); 162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Outputs to the final destination as many full line pairs as 167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * there are in the pending output, removing those lines from 168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * their respective buffers. This method terminates when at 169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * least one of the two column buffers is empty. 170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private void outputFullLines() throws IOException { 172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (;;) { 173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int leftLen = leftBuf.indexOf("\n"); 174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (leftLen < 0) { 175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return; 176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int rightLen = rightBuf.indexOf("\n"); 179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (rightLen < 0) { 180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return; 181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (leftLen != 0) { 184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.write(leftBuf.substring(0, leftLen)); 185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (rightLen != 0) { 188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul writeSpaces(out, leftWidth - leftLen); 189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.write(rightBuf.substring(0, rightLen)); 190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.write('\n'); 193917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 194917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul leftBuf.delete(0, leftLen + 1); 195917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul rightBuf.delete(0, rightLen + 1); 196917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 197917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 198917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 199917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 200917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Flushes the left column buffer, printing it and clearing the buffer. 201917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * If the buffer is already empty, this does nothing. 202917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 203917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private void flushLeft() throws IOException { 204917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul appendNewlineIfNecessary(leftBuf, leftColumn); 205917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 206917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul while (leftBuf.length() != 0) { 207917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul rightColumn.write('\n'); 208917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul outputFullLines(); 209917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 210917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 211917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 212917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 213917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Flushes the right column buffer, printing it and clearing the buffer. 214917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * If the buffer is already empty, this does nothing. 215917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 216917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private void flushRight() throws IOException { 217917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul appendNewlineIfNecessary(rightBuf, rightColumn); 218917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 219917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul while (rightBuf.length() != 0) { 220917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul leftColumn.write('\n'); 221917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul outputFullLines(); 222917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 223917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 224917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 225917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 226917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Appends a newline to the given buffer via the given writer, but 227917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * only if it isn't empty and doesn't already end with one. 228917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 229917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param buf {@code non-null;} the buffer in question 230917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param out {@code non-null;} the writer to use 231917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 232917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private static void appendNewlineIfNecessary(StringBuffer buf, 233917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Writer out) 234917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throws IOException { 235917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int len = buf.length(); 236917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 237917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if ((len != 0) && (buf.charAt(len - 1) != '\n')) { 238917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.write('\n'); 239917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 240917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 241917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 242917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 243917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Writes the given number of spaces to the given writer. 244917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 245917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param out {@code non-null;} where to write 246917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param amt {@code >= 0;} the number of spaces to write 247917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 248917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private static void writeSpaces(Writer out, int amt) throws IOException { 249917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul while (amt > 0) { 250917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.write(' '); 251917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul amt--; 252917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 253917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 254917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 255