Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright 2013, Google Inc.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  *     * Redistributions of source code must retain the above copyright
     10  * notice, this list of conditions and the following disclaimer.
     11  *     * Redistributions in binary form must reproduce the above
     12  * copyright notice, this list of conditions and the following disclaimer
     13  * in the documentation and/or other materials provided with the
     14  * distribution.
     15  *     * Neither the name of Google Inc. nor the names of its
     16  * contributors may be used to endorse or promote products derived from
     17  * this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 package org.jf.util;
     33 
     34 import javax.annotation.Nonnull;
     35 import java.io.IOException;
     36 import java.io.OutputStream;
     37 import java.io.OutputStreamWriter;
     38 import java.io.Writer;
     39 
     40 /**
     41  * Class that takes a combined output destination and provides two
     42  * output writers, one of which ends up writing to the left column and
     43  * one which goes on the right.
     44  */
     45 public final class TwoColumnOutput {
     46     /** non-null; underlying writer for final output */
     47     private final Writer out;
     48 
     49     /** > 0; the left column width */
     50     private final int leftWidth;
     51 
     52     private final int rightWidth;
     53 
     54     private final String spacer;
     55 
     56     /**
     57      * Constructs an instance.
     58      *
     59      * @param out non-null; writer to send final output to
     60      * @param leftWidth > 0; width of the left column, in characters
     61      * @param rightWidth > 0; width of the right column, in characters
     62      * @param spacer non-null; spacer string to sit between the two columns
     63      */
     64     public TwoColumnOutput(@Nonnull Writer out, int leftWidth, int rightWidth,
     65                            @Nonnull String spacer) {
     66 
     67         if (leftWidth < 1) {
     68             throw new IllegalArgumentException("leftWidth < 1");
     69         }
     70 
     71         if (rightWidth < 1) {
     72             throw new IllegalArgumentException("rightWidth < 1");
     73         }
     74 
     75         this.out = out;
     76         this.leftWidth = leftWidth;
     77         this.rightWidth = rightWidth;
     78         this.spacer = spacer;
     79     }
     80 
     81     /**
     82      * Constructs an instance.
     83      *
     84      * @param out non-null; stream to send final output to
     85      * @param leftWidth &gt;= 1; width of the left column, in characters
     86      * @param rightWidth &gt;= 1; width of the right column, in characters
     87      * @param spacer non-null; spacer string to sit between the two columns
     88      */
     89     public TwoColumnOutput(OutputStream out, int leftWidth, int rightWidth,
     90                            String spacer) {
     91         this(new OutputStreamWriter(out), leftWidth, rightWidth, spacer);
     92     }
     93 
     94     private String[] leftLines = null;
     95     private String[] rightLines = null;
     96     public void write(String left, String right) throws IOException {
     97         leftLines = StringWrapper.wrapString(left, leftWidth, leftLines);
     98         rightLines = StringWrapper.wrapString(right, rightWidth, rightLines);
     99         int leftCount = leftLines.length;
    100         int rightCount = rightLines.length;
    101 
    102         for (int i=0; i<leftCount || i <rightCount; i++) {
    103             String leftLine = null;
    104             String rightLine = null;
    105 
    106             if (i < leftCount) {
    107                 leftLine = leftLines[i];
    108                 if (leftLine == null) {
    109                     leftCount = i;
    110                 }
    111             }
    112 
    113             if (i < rightCount) {
    114                 rightLine = rightLines[i];
    115                 if (rightLine == null) {
    116                     rightCount = i;
    117                 }
    118             }
    119 
    120             if (leftLine != null || rightLine != null) {
    121                 int written = 0;
    122                 if (leftLine != null) {
    123                     out.write(leftLine);
    124                     written = leftLine.length();
    125                 }
    126 
    127                 int remaining = leftWidth - written;
    128                 if (remaining > 0) {
    129                     writeSpaces(out, remaining);
    130                 }
    131 
    132                 out.write(spacer);
    133 
    134                 if (rightLine != null) {
    135                     out.write(rightLine);
    136                 }
    137 
    138                 out.write('\n');
    139             }
    140         }
    141     }
    142 
    143     /**
    144      * Writes the given number of spaces to the given writer.
    145      *
    146      * @param out non-null; where to write
    147      * @param amt &gt;= 0; the number of spaces to write
    148      */
    149     private static void writeSpaces(Writer out, int amt) throws IOException {
    150         while (amt > 0) {
    151             out.write(' ');
    152             amt--;
    153         }
    154     }
    155 }
    156