Home | History | Annotate | Download | only in io
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package java.io;
     19 
     20 import java.util.Arrays;
     21 
     22 /**
     23  * A specialized {@link Writer} that writes characters to a {@code StringBuffer}
     24  * in a sequential manner, appending them in the process. The result can later
     25  * be queried using the {@link #StringWriter(int)} or {@link #toString()}
     26  * methods.
     27  *
     28  * @see StringReader
     29  */
     30 public class StringWriter extends Writer {
     31 
     32     private StringBuffer buf;
     33 
     34     /**
     35      * Constructs a new {@code StringWriter} which has a {@link StringBuffer}
     36      * allocated with the default size of 16 characters. The {@code
     37      * StringBuffer} is also the {@code lock} used to synchronize access to this
     38      * writer.
     39      */
     40     public StringWriter() {
     41         buf = new StringBuffer(16);
     42         lock = buf;
     43     }
     44 
     45     /**
     46      * Constructs a new {@code StringWriter} which has a {@link StringBuffer}
     47      * allocated with a size of {@code initialSize} characters. The {@code
     48      * StringBuffer} is also the {@code lock} used to synchronize access to this
     49      * writer.
     50      *
     51      * @param initialSize
     52      *            the intial size of the target string buffer.
     53      */
     54     public StringWriter(int initialSize) {
     55         if (initialSize < 0) {
     56             throw new IllegalArgumentException();
     57         }
     58         buf = new StringBuffer(initialSize);
     59         lock = buf;
     60     }
     61 
     62     /**
     63      * Calling this method has no effect. In contrast to most {@code Writer} subclasses,
     64      * the other methods in {@code StringWriter} do not throw an {@code IOException} if
     65      * {@code close()} has been called.
     66      *
     67      * @throws IOException
     68      *             if an error occurs while closing this writer.
     69      */
     70     @Override
     71     public void close() throws IOException {
     72         /* empty */
     73     }
     74 
     75     /**
     76      * Calling this method has no effect.
     77      */
     78     @Override
     79     public void flush() {
     80         /* empty */
     81     }
     82 
     83     /**
     84      * Gets a reference to this writer's internal {@link StringBuffer}. Any
     85      * changes made to the returned buffer are reflected in this writer.
     86      *
     87      * @return a reference to this writer's internal {@code StringBuffer}.
     88      */
     89     public StringBuffer getBuffer() {
     90         return buf;
     91     }
     92 
     93     /**
     94      * Gets a copy of the contents of this writer as a string.
     95      *
     96      * @return this writer's contents as a string.
     97      */
     98     @Override
     99     public String toString() {
    100         return buf.toString();
    101     }
    102 
    103     /**
    104      * Writes {@code count} characters starting at {@code offset} in {@code buf}
    105      * to this writer's {@code StringBuffer}.
    106      *
    107      * @param chars
    108      *            the non-null character array to write.
    109      * @param offset
    110      *            the index of the first character in {@code chars} to write.
    111      * @param count
    112      *            the maximum number of characters to write.
    113      * @throws IndexOutOfBoundsException
    114      *             if {@code offset < 0} or {@code count < 0}, or if {@code
    115      *             offset + count} is greater than the size of {@code buf}.
    116      */
    117     @Override
    118     public void write(char[] chars, int offset, int count) {
    119         Arrays.checkOffsetAndCount(chars.length, offset, count);
    120         if (count == 0) {
    121             return;
    122         }
    123         buf.append(chars, offset, count);
    124     }
    125 
    126     /**
    127      * Writes one character to this writer's {@code StringBuffer}. Only the two
    128      * least significant bytes of the integer {@code oneChar} are written.
    129      *
    130      * @param oneChar
    131      *            the character to write to this writer's {@code StringBuffer}.
    132      */
    133     @Override
    134     public void write(int oneChar) {
    135         buf.append((char) oneChar);
    136     }
    137 
    138     /**
    139      * Writes the characters from the specified string to this writer's {@code
    140      * StringBuffer}.
    141      *
    142      * @param str
    143      *            the non-null string containing the characters to write.
    144      */
    145     @Override
    146     public void write(String str) {
    147         buf.append(str);
    148     }
    149 
    150     /**
    151      * Writes {@code count} characters from {@code str} starting at {@code
    152      * offset} to this writer's {@code StringBuffer}.
    153      *
    154      * @param str
    155      *            the non-null string containing the characters to write.
    156      * @param offset
    157      *            the index of the first character in {@code str} to write.
    158      * @param count
    159      *            the number of characters from {@code str} to write.
    160      * @throws StringIndexOutOfBoundsException
    161      *             if {@code offset < 0} or {@code count < 0}, or if {@code
    162      *             offset + count} is greater than the length of {@code str}.
    163      */
    164     @Override
    165     public void write(String str, int offset, int count) {
    166         String sub = str.substring(offset, offset + count);
    167         buf.append(sub);
    168     }
    169 
    170     /**
    171      * Appends the character {@code c} to this writer's {@code StringBuffer}.
    172      * This method works the same way as {@link #write(int)}.
    173      *
    174      * @param c
    175      *            the character to append to the target stream.
    176      * @return this writer.
    177      */
    178     @Override
    179     public StringWriter append(char c) {
    180         write(c);
    181         return this;
    182     }
    183 
    184     /**
    185      * Appends the character sequence {@code csq} to this writer's {@code
    186      * StringBuffer}. This method works the same way as {@code
    187      * StringWriter.write(csq.toString())}. If {@code csq} is {@code null}, then
    188      * the string "null" is written to the target stream.
    189      *
    190      * @param csq
    191      *            the character sequence appended to the target.
    192      * @return this writer.
    193      */
    194     @Override
    195     public StringWriter append(CharSequence csq) {
    196         if (csq == null) {
    197             csq = "null";
    198         }
    199         write(csq.toString());
    200         return this;
    201     }
    202 
    203     /**
    204      * Appends a subsequence of the character sequence {@code csq} to this
    205      * writer's {@code StringBuffer}. This method works the same way as {@code
    206      * StringWriter.writer(csq.subsequence(start, end).toString())}. If {@code
    207      * csq} is {@code null}, then the specified subsequence of the string "null"
    208      * will be written to the target.
    209      *
    210      * @param csq
    211      *            the character sequence appended to the target.
    212      * @param start
    213      *            the index of the first char in the character sequence appended
    214      *            to the target.
    215      * @param end
    216      *            the index of the character following the last character of the
    217      *            subsequence appended to the target.
    218      * @return this writer.
    219      * @throws IndexOutOfBoundsException
    220      *             if {@code start > end}, {@code start < 0}, {@code end < 0} or
    221      *             either {@code start} or {@code end} are greater or equal than
    222      *             the length of {@code csq}.
    223      */
    224     @Override
    225     public StringWriter append(CharSequence csq, int start, int end) {
    226         if (csq == null) {
    227             csq = "null";
    228         }
    229         String output = csq.subSequence(start, end).toString();
    230         write(output, 0, output.length());
    231         return this;
    232     }
    233 }
    234