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
18package tests.support;
19
20import java.io.IOException;
21import java.io.Writer;
22
23public class Support_StringWriter extends Writer {
24    private StringBuffer buf;
25
26    /**
27     * Constructs a new StringWriter which has a StringBuffer allocated with the
28     * default size of 16 characters. The StringBuffer is also the
29     * <code>lock</code> used to synchronize access to this Writer.
30     */
31    public Support_StringWriter() {
32        super();
33        buf = new StringBuffer(16);
34        lock = buf;
35    }
36
37    /**
38     * Constructs a new StringWriter which has a StringBuffer allocated with the
39     * size of <code>initialSize</code> characters. The StringBuffer is also
40     * the <code>lock</code> used to synchronize access to this Writer.
41     */
42    public Support_StringWriter(int initialSize) {
43        if (initialSize >= 0) {
44            buf = new StringBuffer(initialSize);
45            lock = buf;
46        } else {
47            throw new IllegalArgumentException();
48        }
49    }
50
51    /**
52     * Close this Writer. This is the concrete implementation required. This
53     * particular implementation does nothing.
54     *
55     * @throws java.io.IOException If an IO error occurs closing this StringWriter.
56     */
57    @Override
58    public void close() throws IOException {
59    }
60
61    /**
62     * Flush this Writer. This is the concrete implementation required. This
63     * particular implementation does nothing.
64     */
65    @Override
66    public void flush() {
67    }
68
69    /**
70     * Answer the contents of this StringWriter as a StringBuffer. Any changes
71     * made to the StringBuffer by the receiver or the caller are reflected in
72     * this StringWriter.
73     *
74     * @return this StringWriters local StringBuffer.
75     */
76    public StringBuffer getBuffer() {
77        synchronized (lock) {
78            return buf;
79        }
80    }
81
82    /**
83     * Answer the contents of this StringWriter as a String. Any changes made to
84     * the StringBuffer by the receiver after returning will not be reflected in
85     * the String returned to the caller.
86     *
87     * @return this StringWriters current contents as a String.
88     */
89    @Override
90    public String toString() {
91        synchronized (lock) {
92            return buf.toString();
93        }
94    }
95
96    /**
97     * Writes <code>count</code> characters starting at <code>offset</code>
98     * in <code>buf</code> to this StringWriter.
99     *
100     * @param buf    the non-null array containing characters to write.
101     * @param offset offset in buf to retrieve characters
102     * @param count  maximum number of characters to write
103     * @throws java.lang.ArrayIndexOutOfBoundsException
104     *          If offset or count are outside of bounds.
105     */
106    @Override
107    public void write(char[] buf, int offset, int count) {
108        // avoid int overflow
109        if (0 <= offset && offset <= buf.length && 0 <= count
110                && count <= buf.length - offset) {
111            synchronized (lock) {
112                this.buf.append(buf, offset, count);
113            }
114        } else {
115            throw new ArrayIndexOutOfBoundsException();
116        }
117    }
118
119    /**
120     * Writes the specified character <code>oneChar</code> to this
121     * StringWriter. This implementation writes the low order two bytes to the
122     * Stream.
123     *
124     * @param oneChar The character to write
125     */
126    @Override
127    public void write(int oneChar) {
128        synchronized (lock) {
129            buf.append((char) oneChar);
130        }
131    }
132
133    /**
134     * Writes the characters from the String <code>str</code> to this
135     * StringWriter.
136     *
137     * @param str the non-null String containing the characters to write.
138     */
139    @Override
140    public void write(String str) {
141        synchronized (lock) {
142            buf.append(str);
143        }
144    }
145
146    /**
147     * Writes <code>count</code> number of characters starting at
148     * <code>offset</code> from the String <code>str</code> to this
149     * StringWriter.
150     *
151     * @param str    the non-null String containing the characters to write.
152     * @param offset the starting point to retrieve characters.
153     * @param count  the number of characters to retrieve and write.
154     * @throws java.lang.ArrayIndexOutOfBoundsException
155     *          If offset or count are outside of bounds.
156     */
157    @Override
158    public void write(String str, int offset, int count) {
159        String sub = str.substring(offset, offset + count);
160        synchronized (lock) {
161            buf.append(sub);
162        }
163    }
164}
165