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 package org.apache.commons.io.output; 18 19 import java.io.IOException; 20 import java.io.Writer; 21 import java.util.Objects; 22 23 /** 24 * Writer implementation that writes the data to an {@link Appendable} 25 * Object. 26 * <p> 27 * For example, can be used with a {@link StringBuilder} 28 * or {@link StringBuffer}. 29 * </p> 30 * 31 * @since 2.7 32 * @see Appendable 33 * @param <T> The type of the {@link Appendable} wrapped by this AppendableWriter. 34 */ 35 public class AppendableWriter <T extends Appendable> extends Writer { 36 37 private final T appendable; 38 39 /** 40 * Constructs a new instance with the specified appendable. 41 * 42 * @param appendable the appendable to write to 43 */ 44 public AppendableWriter(final T appendable) { 45 this.appendable = appendable; 46 } 47 48 /** 49 * Appends the specified character to the underlying appendable. 50 * 51 * @param c the character to append 52 * @return this writer 53 * @throws IOException upon error 54 */ 55 @Override 56 public Writer append(final char c) throws IOException { 57 appendable.append(c); 58 return this; 59 } 60 61 /** 62 * Appends the specified character sequence to the underlying appendable. 63 * 64 * @param csq the character sequence to append 65 * @return this writer 66 * @throws IOException upon error 67 */ 68 @Override 69 public Writer append(final CharSequence csq) throws IOException { 70 appendable.append(csq); 71 return this; 72 } 73 74 /** 75 * Appends a subsequence of the specified character sequence to the underlying appendable. 76 * 77 * @param csq the character sequence from which a subsequence will be appended 78 * @param start the index of the first character in the subsequence 79 * @param end the index of the character following the last character in the subsequence 80 * @return this writer 81 * @throws IOException upon error 82 */ 83 @Override 84 public Writer append(final CharSequence csq, final int start, final int end) throws IOException { 85 appendable.append(csq, start, end); 86 return this; 87 } 88 89 /** 90 * Closes the stream. This implementation does nothing. 91 * 92 * @throws IOException upon error 93 */ 94 @Override 95 public void close() throws IOException { 96 // noop 97 } 98 99 /** 100 * Flushes the stream. This implementation does nothing. 101 * 102 * @throws IOException upon error 103 */ 104 @Override 105 public void flush() throws IOException { 106 // noop 107 } 108 109 /** 110 * Gets the target appendable. 111 * 112 * @return the target appendable 113 */ 114 public T getAppendable() { 115 return appendable; 116 } 117 118 /** 119 * Writes a portion of an array of characters to the underlying appendable. 120 * 121 * @param cbuf an array with the characters to write 122 * @param off offset from which to start writing characters 123 * @param len number of characters to write 124 * @throws IOException upon error 125 */ 126 @Override 127 public void write(final char[] cbuf, final int off, final int len) throws IOException { 128 Objects.requireNonNull(cbuf, "cbuf"); 129 if (len < 0 || off + len > cbuf.length) { 130 throw new IndexOutOfBoundsException("Array Size=" + cbuf.length + 131 ", offset=" + off + ", length=" + len); 132 } 133 for (int i = 0; i < len; i++) { 134 appendable.append(cbuf[off + i]); 135 } 136 } 137 138 /** 139 * Writes a character to the underlying appendable. 140 * 141 * @param c the character to write 142 * @throws IOException upon error 143 */ 144 @Override 145 public void write(final int c) throws IOException { 146 appendable.append((char) c); 147 } 148 149 /** 150 * Writes a portion of a String to the underlying appendable. 151 * 152 * @param str a string 153 * @param off offset from which to start writing characters 154 * @param len number of characters to write 155 * @throws IOException upon error 156 */ 157 @Override 158 public void write(final String str, final int off, final int len) throws IOException { 159 // appendable.append will add "null" for a null String; add an explicit null check 160 Objects.requireNonNull(str, "str"); 161 appendable.append(str, off, off + len); 162 } 163 164 }