1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.io;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20a1603838fe9e865575c87982e32c6343740e464cElliott Hughesimport java.util.Arrays;
21aa37e2512b13deab2e82800c71327dd74c362577Elliott Hughesimport libcore.util.SneakyThrow;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Wraps an existing {@link Writer} and <em>buffers</em> the output. Expensive
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interaction with the underlying reader is minimized, since most (smaller)
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * requests can be satisfied by accessing the buffer alone. The drawback is that
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * some extra space is required to hold the buffer and that copying takes place
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * when filling that buffer, but this is usually outweighed by the performance
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * benefits.
30f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p/>A typical application pattern for the class looks like this:<p/>
32f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre>
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * BufferedWriter buf = new BufferedWriter(new FileWriter(&quot;file.java&quot;));
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre>
36f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see BufferedReader
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class BufferedWriter extends Writer {
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Writer out;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
43171dc20afe5071d5cbfad7103903bfa2c1f8d00fElliott Hughes    private char[] buf;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int pos;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
48fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes     * Constructs a new {@code BufferedWriter}, providing {@code out} with a buffer
49fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson     * of 8192 chars.
50f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
51fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes     * @param out the {@code Writer} the buffer writes to.
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BufferedWriter(Writer out) {
54fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes        this(out, 8192);
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
58fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson     * Constructs a new {@code BufferedWriter}, providing {@code out} with {@code size} chars
59fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes     * of buffer.
60f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
61fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes     * @param out the {@code OutputStream} the buffer writes to.
62fd1bbd5cb70830aaf6639dafc240c4d17181ef75Jesse Wilson     * @param size the size of buffer in chars.
63fb4616d0efbba1903b9237c0a428b59868365a69Elliott Hughes     * @throws IllegalArgumentException if {@code size <= 0}.
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BufferedWriter(Writer out, int size) {
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super(out);
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (size <= 0) {
68b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IllegalArgumentException("size <= 0");
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.out = out;
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.buf = new char[size];
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes this writer. The contents of the buffer are flushed, the target
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * writer is closed, and the buffer is released. Only the first invocation
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of close has any effect.
78f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while closing this writer.
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void close() throws IOException {
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (lock) {
8555392539fea537abfb6581b474918f9d611fba27Jesse Wilson            if (isClosed()) {
8655392539fea537abfb6581b474918f9d611fba27Jesse Wilson                return;
8755392539fea537abfb6581b474918f9d611fba27Jesse Wilson            }
8855392539fea537abfb6581b474918f9d611fba27Jesse Wilson
8955392539fea537abfb6581b474918f9d611fba27Jesse Wilson            Throwable thrown = null;
9055392539fea537abfb6581b474918f9d611fba27Jesse Wilson            try {
91f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson                flushInternal();
9255392539fea537abfb6581b474918f9d611fba27Jesse Wilson            } catch (Throwable e) {
9355392539fea537abfb6581b474918f9d611fba27Jesse Wilson                thrown = e;
9455392539fea537abfb6581b474918f9d611fba27Jesse Wilson            }
9555392539fea537abfb6581b474918f9d611fba27Jesse Wilson            buf = null;
9655392539fea537abfb6581b474918f9d611fba27Jesse Wilson
9755392539fea537abfb6581b474918f9d611fba27Jesse Wilson            try {
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                out.close();
9955392539fea537abfb6581b474918f9d611fba27Jesse Wilson            } catch (Throwable e) {
10055392539fea537abfb6581b474918f9d611fba27Jesse Wilson                if (thrown == null) {
10155392539fea537abfb6581b474918f9d611fba27Jesse Wilson                    thrown = e;
10255392539fea537abfb6581b474918f9d611fba27Jesse Wilson                }
10355392539fea537abfb6581b474918f9d611fba27Jesse Wilson            }
10455392539fea537abfb6581b474918f9d611fba27Jesse Wilson            out = null;
10555392539fea537abfb6581b474918f9d611fba27Jesse Wilson
10655392539fea537abfb6581b474918f9d611fba27Jesse Wilson            if (thrown != null) {
10755392539fea537abfb6581b474918f9d611fba27Jesse Wilson                SneakyThrow.sneakyThrow(thrown);
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Flushes this writer. The contents of the buffer are committed to the
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * target writer and it is then flushed.
115f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs while flushing this writer.
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void flush() throws IOException {
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (lock) {
122b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            checkNotClosed();
123f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            flushInternal();
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            out.flush();
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
128b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    private void checkNotClosed() throws IOException {
129b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        if (isClosed()) {
130b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            throw new IOException("BufferedWriter is closed");
131b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes        }
132b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes    }
133b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
135f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * Flushes the internal buffer.
136f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     */
137f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    private void flushInternal() throws IOException {
138f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        if (pos > 0) {
139f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson            out.write(buf, 0, pos);
140f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        }
141f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson        pos = 0;
142f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    }
143f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson
144f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson    /**
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Indicates whether this writer is closed.
146f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if this writer is closed, {@code false} otherwise.
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isClosed() {
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return out == null;
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
154b4acb463582a510894aeb85f4fa8f35b339449c8Elliott Hughes     * Writes a newline to this writer. On Android, this is {@code "\n"}.
155b4acb463582a510894aeb85f4fa8f35b339449c8Elliott Hughes     * The target writer may or may not be flushed when a newline is written.
156f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs attempting to write to this writer.
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void newLine() throws IOException {
161b4acb463582a510894aeb85f4fa8f35b339449c8Elliott Hughes        write(System.lineSeparator());
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Writes {@code count} characters starting at {@code offset} in
166d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root     * {@code buffer} to this writer. If {@code count} is greater than this
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * writer's buffer, then the buffer is flushed and the characters are
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * written directly to the target writer.
169f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
170d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root     * @param buffer
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the array containing characters to write.
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
173d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root     *            the start position in {@code buffer} for retrieving characters.
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param count
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the maximum number of characters to write.
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset < 0} or {@code count < 0}, or if
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code offset + count} is greater than the size of
179d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root     *             {@code buffer}.
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this writer is closed or another I/O error occurs.
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
184d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root    public void write(char[] buffer, int offset, int count) throws IOException {
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (lock) {
186b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            checkNotClosed();
187d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root            if (buffer == null) {
188b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes                throw new NullPointerException("buffer == null");
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
190d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root            Arrays.checkOffsetAndCount(buffer.length, offset, count);
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (pos == 0 && count >= this.buf.length) {
192d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root                out.write(buffer, offset, count);
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int available = this.buf.length - pos;
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (count < available) {
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                available = count;
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (available > 0) {
200d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root                System.arraycopy(buffer, offset, this.buf, pos, available);
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                pos += available;
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (pos == this.buf.length) {
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                out.write(this.buf, 0, this.buf.length);
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                pos = 0;
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (count > available) {
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    offset += available;
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    available = count - available;
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (available >= this.buf.length) {
210d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root                        out.write(buffer, offset, available);
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return;
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
214d43b9ef11a1095967a3396b246639b563e1a4128Kenny Root                    System.arraycopy(buffer, offset, this.buf, pos, available);
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    pos += available;
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Writes the character {@code oneChar} to this writer. If the buffer
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * gets full by writing this character, this writer is flushed. Only the
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * lower two bytes of the integer {@code oneChar} are written.
225f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param oneChar
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the character to write.
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this writer is closed or another I/O error occurs.
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void write(int oneChar) throws IOException {
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (lock) {
234b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            checkNotClosed();
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (pos >= buf.length) {
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                out.write(buf, 0, buf.length);
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                pos = 0;
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            buf[pos++] = (char) oneChar;
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Writes {@code count} characters starting at {@code offset} in {@code str}
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * to this writer. If {@code count} is greater than this writer's buffer,
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * then this writer is flushed and the remaining characters are written
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * directly to the target writer. If count is negative no characters are
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * written to the buffer. This differs from the behavior of the superclass.
249f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param str
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the non-null String containing characters to write.
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the start position in {@code str} for retrieving characters.
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param count
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            maximum number of characters to write.
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this writer has already been closed or another I/O error
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             occurs.
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset < 0} or {@code offset + count} is greater
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             than the length of {@code str}.
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void write(String str, int offset, int count) throws IOException {
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (lock) {
266b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes            checkNotClosed();
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (count <= 0) {
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
27044a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes            if (offset < 0 || offset > str.length() - count) {
27144a9f03a2d602c7179112284d878b0db9284eb30Elliott Hughes                throw new StringIndexOutOfBoundsException(str, offset, count);
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (pos == 0 && count >= buf.length) {
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                char[] chars = new char[count];
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                str.getChars(offset, offset + count, chars, 0);
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                out.write(chars, 0, count);
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return;
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int available = buf.length - pos;
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (count < available) {
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                available = count;
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (available > 0) {
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                str.getChars(offset, offset + available, buf, pos);
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                pos += available;
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (pos == buf.length) {
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                out.write(this.buf, 0, this.buf.length);
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                pos = 0;
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (count > available) {
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    offset += available;
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    available = count - available;
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (available >= buf.length) {
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        char[] chars = new char[count];
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        str.getChars(offset, offset + available, chars, 0);
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        out.write(chars, 0, available);
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return;
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    str.getChars(offset, offset + available, buf, pos);
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    pos += available;
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
306