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