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 * https://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 }