1cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath/*
2cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  Licensed to the Apache Software Foundation (ASF) under one or more
3cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  contributor license agreements.  See the NOTICE file distributed with
4cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  this work for additional information regarding copyright ownership.
5cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  The ASF licenses this file to You under the Apache License, Version 2.0
6cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  (the "License"); you may not use this file except in compliance with
7cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  the License.  You may obtain a copy of the License at
8cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *
9cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *     http://www.apache.org/licenses/LICENSE-2.0
10cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *
11cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  Unless required by applicable law or agreed to in writing, software
12cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  distributed under the License is distributed on an "AS IS" BASIS,
13cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  See the License for the specific language governing permissions and
15cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath *  limitations under the License.
16cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */
17cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
18cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathpackage org.apache.harmony.testframework;
19cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
20cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport junit.framework.TestCase;
21cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport junit.framework.TestSuite;
22cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
23cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport java.io.IOException;
24cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport java.io.Writer;
25cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
26cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath/**
27cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Tests behaviour common to wrapping and filtering implementations of {@link
28cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Writer}.
29cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */
30cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathpublic abstract class CharWrapperTester {
31cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
32cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    private boolean throwsExceptions = true;
33cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
34cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    /**
35cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * Creates a new output stream that receives one stream of chars, optionally
36cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * transforms it, and emits another stream of chars to {@code delegate}.
37cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     */
38cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    public abstract Writer create(Writer delegate) throws Exception;
39cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
40cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    /**
41cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * Decodes the chars received by the delegate into their original form: the
42cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * chars originally received by this wrapper.
43cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     */
44cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    public abstract char[] decode(char[] delegateChars) throws Exception;
45cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
46cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    /**
47cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * Configures whether the writer is expected to throw exceptions when an
48cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * error is encountered. Classes like {@code PrintWriter} report errors via
49cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * an API method instead.
50cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     */
51cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    public CharWrapperTester setThrowsExceptions(boolean throwsExceptions) {
52cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        this.throwsExceptions = throwsExceptions;
53cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        return this;
54cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
55cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
56cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    public final TestSuite createTests() {
57cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        TestSuite result = new TestSuite();
58cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        result.addTest(new WrapperSinkTester()
59cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                .setThrowsExceptions(throwsExceptions)
60cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                .createTests());
61cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
62cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        if (throwsExceptions) {
63cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlush"));
64cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaClose"));
65cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            result.addTest(new WrapperTestCase("wrapperTestCloseThrows"));
66cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        } else {
67cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaFlushSuppressed"));
68cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            result.addTest(new WrapperTestCase("wrapperTestFlushThrowsViaCloseSuppressed"));
69cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            result.addTest(new WrapperTestCase("wrapperTestCloseThrowsSuppressed"));
70cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
71cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
72cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        return result;
73cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
74cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
75cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    @Override
76cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    public String toString() {
77cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        return getClass().getName();
78cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
79cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
80cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    private class WrapperSinkTester extends CharSinkTester {
81cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        private ClosableStringWriter delegate;
82cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
83cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
84cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public Writer create() throws Exception {
85cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            delegate = new ClosableStringWriter();
86cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            return CharWrapperTester.this.create(delegate);
87cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
88cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
89cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
90cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public char[] getChars() throws Exception {
91cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            return decode(delegate.buffer.toString().toCharArray());
92cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
93cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
94cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
95cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public String toString() {
96cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            return CharWrapperTester.this.toString();
97cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
98cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
99cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
100cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    public class WrapperTestCase extends TestCase {
101cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
102cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        private WrapperTestCase(String name) {
103cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            super(name);
104cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
105cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
106cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
107cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public String getName() {
108cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            return CharWrapperTester.this.toString() + ":" + super.getName();
109cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
110cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
111cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void wrapperTestFlushThrowsViaFlushSuppressed() throws Exception {
112cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            FailOnFlushWriter delegate = new FailOnFlushWriter();
113cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            Writer o = create(delegate);
114cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            o.write("BUT");
115cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            o.write("TERS");
116cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            o.flush();
117cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            assertTrue(delegate.flushed);
118cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
119cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
120cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void wrapperTestFlushThrowsViaCloseSuppressed() throws Exception {
121cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            FailOnFlushWriter delegate = new FailOnFlushWriter();
122cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            Writer o = create(delegate);
123cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            o.write("BUT");
124cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            o.write("TERS");
125cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            o.close();
126cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            assertTrue(delegate.flushed);
127cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
128cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
129cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void wrapperTestFlushThrowsViaFlush() throws Exception {
130cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            FailOnFlushWriter delegate = new FailOnFlushWriter();
131cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
132cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            Writer o = create(delegate);
133cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            try {
134cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                // any of these is permitted to flush
135cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                o.write("BUT");
136cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                o.write("TERS");
137cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                o.flush();
138cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                assertTrue(delegate.flushed);
139cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                fail("flush exception ignored");
140cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            } catch (IOException expected) {
141cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                assertEquals("Flush failed", expected.getMessage());
142cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            }
143cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
144cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
145cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void wrapperTestFlushThrowsViaClose() throws Exception {
146cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            FailOnFlushWriter delegate = new FailOnFlushWriter();
147cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
148cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            Writer o = create(delegate);
149cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            try {
150cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                // any of these is permitted to flush
151cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                o.write("BUT");
152cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                o.write("TERS");
153cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                o.close();
154cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                assertTrue(delegate.flushed);
155cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                fail("flush exception ignored");
156cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            } catch (IOException expected) {
157cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                assertEquals("Flush failed", expected.getMessage());
158cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            }
159cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
160cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            try {
161cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                o.write("BARK");
162cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                fail("expected already closed exception");
163cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            } catch (IOException expected) {
164cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            }
165cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
166cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
167cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void wrapperTestCloseThrows() throws Exception {
168cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            FailOnCloseWriter delegate = new FailOnCloseWriter();
169cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            Writer o = create(delegate);
170cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            try {
171cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                o.close();
172cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                assertTrue(delegate.closed);
173cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                fail("close exception ignored");
174cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            } catch (IOException expected) {
175cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                assertEquals("Close failed", expected.getMessage());
176cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            }
177cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
178cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
179cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void wrapperTestCloseThrowsSuppressed() throws Exception {
180cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            FailOnCloseWriter delegate = new FailOnCloseWriter();
181cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            Writer o = create(delegate);
182cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            o.close();
183cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            assertTrue(delegate.closed);
184cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
185cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
186cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        // adding a new test? Don't forget to update createTests().
187cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
188cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
189cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    /**
190cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * A custom Writer that respects the closed state. The built-in StringWriter
191cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     * doesn't respect close(), which makes testing wrapped streams difficult.
192cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath     */
193cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    private static class ClosableStringWriter extends Writer {
194cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        private final StringBuilder buffer = new StringBuilder();
195cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        private boolean closed = false;
196cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
197cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
198cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void close() throws IOException {
199cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            closed = true;
200cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
201cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
202cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
203cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void flush() throws IOException {
204cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
205cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
206cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
207cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void write(char[] buf, int offset, int count) throws IOException {
208cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            if (closed) {
209cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                throw new IOException();
210cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            }
211cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            buffer.append(buf, offset, count);
212cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
213cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
214cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
215cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    private static class FailOnFlushWriter extends Writer {
216cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        boolean flushed = false;
217cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        boolean closed = false;
218cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
219cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
220cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void write(char[] buf, int offset, int count) throws IOException {
221cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            if (closed) {
222cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                throw new IOException("Already closed");
223cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            }
224cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
225cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
226cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
227cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void close() throws IOException {
228cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            closed = true;
229cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            flush();
230cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
231cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
232cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
233cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void flush() throws IOException {
234cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            if (!flushed) {
235cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                flushed = true;
236cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath                throw new IOException("Flush failed");
237cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            }
238cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
239cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
240cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
241cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    private static class FailOnCloseWriter extends Writer {
242cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        boolean closed = false;
243cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
244cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
245cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void flush() throws IOException {
246cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
247cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
248cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
249cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void write(char[] buf, int offset, int count) throws IOException {
250cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
251cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath
252cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        @Override
253cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        public void close() throws IOException {
254cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            closed = true;
255cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath            throw new IOException("Close failed");
256cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath        }
257cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath    }
258cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath}