com.android.dx.util.TwoColumnOutput Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of builder Show documentation
Show all versions of builder Show documentation
Library to build Android applications.
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.dx.util;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
/**
* Class that takes a combined output destination and provides two
* output writers, one of which ends up writing to the left column and
* one which goes on the right.
*/
public final class TwoColumnOutput {
/** {@code non-null;} underlying writer for final output */
private final Writer out;
/** {@code > 0;} the left column width */
private final int leftWidth;
/** {@code non-null;} pending left column output */
private final StringBuffer leftBuf;
/** {@code non-null;} pending right column output */
private final StringBuffer rightBuf;
/** {@code non-null;} left column writer */
private final IndentingWriter leftColumn;
/** {@code non-null;} right column writer */
private final IndentingWriter rightColumn;
/**
* Turns the given two strings (with widths) and spacer into a formatted
* two-column string.
*
* @param s1 {@code non-null;} first string
* @param width1 {@code > 0;} width of the first column
* @param spacer {@code non-null;} spacer string
* @param s2 {@code non-null;} second string
* @param width2 {@code > 0;} width of the second column
* @return {@code non-null;} an appropriately-formatted string
*/
public static String toString(String s1, int width1, String spacer,
String s2, int width2) {
int len1 = s1.length();
int len2 = s2.length();
StringWriter sw = new StringWriter((len1 + len2) * 3);
TwoColumnOutput twoOut =
new TwoColumnOutput(sw, width1, width2, spacer);
try {
twoOut.getLeft().write(s1);
twoOut.getRight().write(s2);
} catch (IOException ex) {
throw new RuntimeException("shouldn't happen", ex);
}
twoOut.flush();
return sw.toString();
}
/**
* Constructs an instance.
*
* @param out {@code non-null;} writer to send final output to
* @param leftWidth {@code > 0;} width of the left column, in characters
* @param rightWidth {@code > 0;} width of the right column, in characters
* @param spacer {@code non-null;} spacer string to sit between the two columns
*/
public TwoColumnOutput(Writer out, int leftWidth, int rightWidth,
String spacer) {
if (out == null) {
throw new NullPointerException("out == null");
}
if (leftWidth < 1) {
throw new IllegalArgumentException("leftWidth < 1");
}
if (rightWidth < 1) {
throw new IllegalArgumentException("rightWidth < 1");
}
if (spacer == null) {
throw new NullPointerException("spacer == null");
}
StringWriter leftWriter = new StringWriter(1000);
StringWriter rightWriter = new StringWriter(1000);
this.out = out;
this.leftWidth = leftWidth;
this.leftBuf = leftWriter.getBuffer();
this.rightBuf = rightWriter.getBuffer();
this.leftColumn = new IndentingWriter(leftWriter, leftWidth);
this.rightColumn =
new IndentingWriter(rightWriter, rightWidth, spacer);
}
/**
* Constructs an instance.
*
* @param out {@code non-null;} stream to send final output to
* @param leftWidth {@code >= 1;} width of the left column, in characters
* @param rightWidth {@code >= 1;} width of the right column, in characters
* @param spacer {@code non-null;} spacer string to sit between the two columns
*/
public TwoColumnOutput(OutputStream out, int leftWidth, int rightWidth,
String spacer) {
this(new OutputStreamWriter(out), leftWidth, rightWidth, spacer);
}
/**
* Gets the writer to use to write to the left column.
*
* @return {@code non-null;} the left column writer
*/
public Writer getLeft() {
return leftColumn;
}
/**
* Gets the writer to use to write to the right column.
*
* @return {@code non-null;} the right column writer
*/
public Writer getRight() {
return rightColumn;
}
/**
* Flushes the output. If there are more lines of pending output in one
* column, then the other column will get filled with blank lines.
*/
public void flush() {
try {
appendNewlineIfNecessary(leftBuf, leftColumn);
appendNewlineIfNecessary(rightBuf, rightColumn);
outputFullLines();
flushLeft();
flushRight();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
/**
* Outputs to the final destination as many full line pairs as
* there are in the pending output, removing those lines from
* their respective buffers. This method terminates when at
* least one of the two column buffers is empty.
*/
private void outputFullLines() throws IOException {
for (;;) {
int leftLen = leftBuf.indexOf("\n");
if (leftLen < 0) {
return;
}
int rightLen = rightBuf.indexOf("\n");
if (rightLen < 0) {
return;
}
if (leftLen != 0) {
out.write(leftBuf.substring(0, leftLen));
}
if (rightLen != 0) {
writeSpaces(out, leftWidth - leftLen);
out.write(rightBuf.substring(0, rightLen));
}
out.write('\n');
leftBuf.delete(0, leftLen + 1);
rightBuf.delete(0, rightLen + 1);
}
}
/**
* Flushes the left column buffer, printing it and clearing the buffer.
* If the buffer is already empty, this does nothing.
*/
private void flushLeft() throws IOException {
appendNewlineIfNecessary(leftBuf, leftColumn);
while (leftBuf.length() != 0) {
rightColumn.write('\n');
outputFullLines();
}
}
/**
* Flushes the right column buffer, printing it and clearing the buffer.
* If the buffer is already empty, this does nothing.
*/
private void flushRight() throws IOException {
appendNewlineIfNecessary(rightBuf, rightColumn);
while (rightBuf.length() != 0) {
leftColumn.write('\n');
outputFullLines();
}
}
/**
* Appends a newline to the given buffer via the given writer, but
* only if it isn't empty and doesn't already end with one.
*
* @param buf {@code non-null;} the buffer in question
* @param out {@code non-null;} the writer to use
*/
private static void appendNewlineIfNecessary(StringBuffer buf,
Writer out)
throws IOException {
int len = buf.length();
if ((len != 0) && (buf.charAt(len - 1) != '\n')) {
out.write('\n');
}
}
/**
* Writes the given number of spaces to the given writer.
*
* @param out {@code non-null;} where to write
* @param amt {@code >= 0;} the number of spaces to write
*/
private static void writeSpaces(Writer out, int amt) throws IOException {
while (amt > 0) {
out.write(' ');
amt--;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy