1dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme/*
2dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme * Copyright (C) 2013 The Android Open Source Project
3dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme *
4dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License");
5dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme * you may not use this file except in compliance with the License.
6dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme * You may obtain a copy of the License at
7dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme *
8dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme *      http://www.apache.org/licenses/LICENSE-2.0
9dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme *
10dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme * Unless required by applicable law or agreed to in writing, software
11dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS,
12dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme * See the License for the specific language governing permissions and
14dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme * limitations under the License.
15dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme */
16dec9200cc76a1e465c97cc078a9927984058678fFelipe Leme
17db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornpackage com.android.internal.util;
18db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
199b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackbornimport android.util.Log;
206d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackbornimport android.util.Printer;
216d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn
22db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.io.IOException;
23db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.io.OutputStream;
24db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.io.PrintWriter;
25db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.io.UnsupportedEncodingException;
26db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.io.Writer;
27db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.nio.ByteBuffer;
28db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.nio.CharBuffer;
29db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.nio.charset.Charset;
30db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.nio.charset.CharsetEncoder;
31db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.nio.charset.CoderResult;
32db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornimport java.nio.charset.CodingErrorAction;
33db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
34db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackbornpublic class FastPrintWriter extends PrintWriter {
35b3d4cb369e37b1b7e85832cc035226dc7cc8f380Dianne Hackborn    private static class DummyWriter extends Writer {
36e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        @Override
37e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        public void close() throws IOException {
38e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            UnsupportedOperationException ex
39e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                    = new UnsupportedOperationException("Shouldn't be here");
40e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            throw ex;
41e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
42e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn
43e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        @Override
44e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        public void flush() throws IOException {
45e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            close();
46e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
47e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn
48e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        @Override
49e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        public void write(char[] buf, int offset, int count) throws IOException {
50e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            close();
51e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
52e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    };
53e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn
548c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn    private final int mBufferLen;
558c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn    private final char[] mText;
56db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    private int mPos;
57db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
58db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    final private OutputStream mOutputStream;
59e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    final private boolean mAutoFlush;
60e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    final private String mSeparator;
618c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn
628c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn    final private Writer mWriter;
636d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn    final private Printer mPrinter;
648c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn
65db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    private CharsetEncoder mCharset;
668c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn    final private ByteBuffer mBytes;
678c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn
68e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    private boolean mIoError;
69db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
70db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
71db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Constructs a new {@code PrintWriter} with {@code out} as its target
72db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * stream. By default, the new print writer does not automatically flush its
73db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * contents to the target stream when a newline is encountered.
74db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
75db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param out
76db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the target output stream.
77db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @throws NullPointerException
78db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             if {@code out} is {@code null}.
79db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
80db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public FastPrintWriter(OutputStream out) {
818c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        this(out, false, 8192);
82db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
83db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
84db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
85db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Constructs a new {@code PrintWriter} with {@code out} as its target
86db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * stream. The parameter {@code autoFlush} determines if the print writer
87db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * automatically flushes its contents to the target stream when a newline is
88db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * encountered.
89db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
90db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param out
91db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the target output stream.
92db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param autoFlush
93db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            indicates whether contents are flushed upon encountering a
94db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            newline sequence.
95db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @throws NullPointerException
96db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             if {@code out} is {@code null}.
97db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
98db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public FastPrintWriter(OutputStream out, boolean autoFlush) {
998c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        this(out, autoFlush, 8192);
1008c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn    }
1018c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn
1028c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn    /**
1038c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * Constructs a new {@code PrintWriter} with {@code out} as its target
1048c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * stream and a custom buffer size. The parameter {@code autoFlush} determines
1058c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * if the print writer automatically flushes its contents to the target stream
1068c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * when a newline is encountered.
1078c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *
1088c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * @param out
1098c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *            the target output stream.
1108c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * @param autoFlush
1118c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *            indicates whether contents are flushed upon encountering a
1128c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *            newline sequence.
1138c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * @param bufferLen
1148c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *            specifies the size of the FastPrintWriter's internal buffer; the
1158c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *            default is 8192.
1168c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * @throws NullPointerException
1178c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *             if {@code out} is {@code null}.
1188c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     */
1198c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn    public FastPrintWriter(OutputStream out, boolean autoFlush, int bufferLen) {
120b3d4cb369e37b1b7e85832cc035226dc7cc8f380Dianne Hackborn        super(new DummyWriter(), autoFlush);
1218c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        if (out == null) {
1228c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn            throw new NullPointerException("out is null");
1238c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        }
1248c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        mBufferLen = bufferLen;
1258c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        mText = new char[bufferLen];
1268c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        mBytes = ByteBuffer.allocate(mBufferLen);
127db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        mOutputStream = out;
128e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        mWriter = null;
1296d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        mPrinter = null;
130e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        mAutoFlush = autoFlush;
131e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        mSeparator = System.lineSeparator();
132db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        initDefaultEncoder();
133db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
134db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
135db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
136db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Constructs a new {@code PrintWriter} with {@code wr} as its target
137db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * writer. By default, the new print writer does not automatically flush its
138db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * contents to the target writer when a newline is encountered.
139db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
1408c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * <p>NOTE: Unlike PrintWriter, this version will still do buffering inside of
1418c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * FastPrintWriter before sending data to the Writer.  This means you must call
1428c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * flush() before retrieving any data from the Writer.</p>
1438c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *
144db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param wr
145db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the target writer.
146db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @throws NullPointerException
147db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             if {@code wr} is {@code null}.
148db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
149db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public FastPrintWriter(Writer wr) {
1508c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        this(wr, false, 8192);
151db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
152db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
153db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
1546d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * Constructs a new {@code PrintWriter} with {@code wr} as its target
155db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * writer. The parameter {@code autoFlush} determines if the print writer
156db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * automatically flushes its contents to the target writer when a newline is
157db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * encountered.
158db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
159db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param wr
160db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the target writer.
161db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param autoFlush
162db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            indicates whether to flush contents upon encountering a
163db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            newline sequence.
164db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @throws NullPointerException
165db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             if {@code out} is {@code null}.
166db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
167db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public FastPrintWriter(Writer wr, boolean autoFlush) {
1688c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        this(wr, autoFlush, 8192);
1698c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn    }
1708c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn
1718c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn    /**
1726d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * Constructs a new {@code PrintWriter} with {@code wr} as its target
1738c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * writer and a custom buffer size. The parameter {@code autoFlush} determines
1748c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * if the print writer automatically flushes its contents to the target writer
1758c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * when a newline is encountered.
1768c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *
1778c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * @param wr
1788c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *            the target writer.
1798c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * @param autoFlush
1808c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *            indicates whether to flush contents upon encountering a
1818c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *            newline sequence.
1828c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * @param bufferLen
1838c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *            specifies the size of the FastPrintWriter's internal buffer; the
1848c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *            default is 8192.
1858c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     * @throws NullPointerException
1868c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     *             if {@code wr} is {@code null}.
1878c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn     */
1888c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn    public FastPrintWriter(Writer wr, boolean autoFlush, int bufferLen) {
189b3d4cb369e37b1b7e85832cc035226dc7cc8f380Dianne Hackborn        super(new DummyWriter(), autoFlush);
1908c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        if (wr == null) {
1918c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn            throw new NullPointerException("wr is null");
1928c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        }
1938c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        mBufferLen = bufferLen;
1948c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        mText = new char[bufferLen];
1958c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        mBytes = null;
196db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        mOutputStream = null;
197e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        mWriter = wr;
1986d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        mPrinter = null;
199e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        mAutoFlush = autoFlush;
200e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        mSeparator = System.lineSeparator();
201db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        initDefaultEncoder();
202db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
203db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
2046d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn    /**
2056d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * Constructs a new {@code PrintWriter} with {@code pr} as its target
2066d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * printer and the default buffer size.  Because a {@link Printer} is line-base,
2076d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * autoflush is always enabled.
2086d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     *
2096d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * @param pr
2106d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     *            the target writer.
2116d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * @throws NullPointerException
2126d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     *             if {@code pr} is {@code null}.
2136d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     */
2146d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn    public FastPrintWriter(Printer pr) {
2156d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        this(pr, 512);
2166d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn    }
2176d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn
2186d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn    /**
2196d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * Constructs a new {@code PrintWriter} with {@code pr} as its target
2206d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * printer and a custom buffer size.  Because a {@link Printer} is line-base,
2216d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * autoflush is always enabled.
2226d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     *
2236d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * @param pr
2246d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     *            the target writer.
2256d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * @param bufferLen
2266d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     *            specifies the size of the FastPrintWriter's internal buffer; the
2276d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     *            default is 512.
2286d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     * @throws NullPointerException
2296d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     *             if {@code pr} is {@code null}.
2306d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn     */
2316d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn    public FastPrintWriter(Printer pr, int bufferLen) {
232b3d4cb369e37b1b7e85832cc035226dc7cc8f380Dianne Hackborn        super(new DummyWriter(), true);
2336d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        if (pr == null) {
2346d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            throw new NullPointerException("pr is null");
2356d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        }
2366d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        mBufferLen = bufferLen;
2376d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        mText = new char[bufferLen];
2386d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        mBytes = null;
2396d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        mOutputStream = null;
2406d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        mWriter = null;
2416d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        mPrinter = pr;
2426d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        mAutoFlush = true;
2436d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        mSeparator = System.lineSeparator();
2446d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn        initDefaultEncoder();
2456d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn    }
2466d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn
247e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    private final void initEncoder(String csn) throws UnsupportedEncodingException {
248e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        try {
249e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            mCharset = Charset.forName(csn).newEncoder();
250e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        } catch (Exception e) {
251e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            throw new UnsupportedEncodingException(csn);
252e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
253e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        mCharset.onMalformedInput(CodingErrorAction.REPLACE);
254e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        mCharset.onUnmappableCharacter(CodingErrorAction.REPLACE);
255db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
256db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
257db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
258e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn     * Flushes this writer and returns the value of the error flag.
259db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
260e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn     * @return {@code true} if either an {@code IOException} has been thrown
261e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn     *         previously or if {@code setError()} has been called;
262e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn     *         {@code false} otherwise.
263e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn     * @see #setError()
264db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
265e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    public boolean checkError() {
266e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        flush();
267e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
268e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            return mIoError;
269e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
270db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
271db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
272db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
273e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn     * Sets the error state of the stream to false.
274e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn     * @since 1.6
275db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
276e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    protected void clearError() {
277e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
278e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            mIoError = false;
279e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
280db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
281db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
282e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    /**
283e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn     * Sets the error flag of this writer to true.
284db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
285e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    protected void setError() {
286e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
287e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            mIoError = true;
288db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
289db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
290db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
291db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    private final void initDefaultEncoder() {
292db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        mCharset = Charset.defaultCharset().newEncoder();
293db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        mCharset.onMalformedInput(CodingErrorAction.REPLACE);
294db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        mCharset.onUnmappableCharacter(CodingErrorAction.REPLACE);
295db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
296db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
297e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    private void appendLocked(char c) throws IOException {
298db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        int pos = mPos;
2998c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        if (pos >= (mBufferLen-1)) {
300e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            flushLocked();
301db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            pos = mPos;
302db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
303db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        mText[pos] = c;
304db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        mPos = pos+1;
305db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
306db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
307e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    private void appendLocked(String str, int i, final int length) throws IOException {
3088c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        final int BUFFER_LEN = mBufferLen;
309db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        if (length > BUFFER_LEN) {
310db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            final int end = i + length;
311db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            while (i < end) {
312db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                int next = i + BUFFER_LEN;
313e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                appendLocked(str, i, next < end ? BUFFER_LEN : (end - i));
314db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                i = next;
315db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            }
316db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            return;
317db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
318db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        int pos = mPos;
319db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        if ((pos+length) > BUFFER_LEN) {
320e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            flushLocked();
321db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            pos = mPos;
322db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
323db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        str.getChars(i, i + length, mText, pos);
324db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        mPos = pos + length;
325db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
326db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
327e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    private void appendLocked(char[] buf, int i, final int length) throws IOException {
3288c84109b9fbbf473b225707a38261ff5f99d95fbDianne Hackborn        final int BUFFER_LEN = mBufferLen;
329db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        if (length > BUFFER_LEN) {
330db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            final int end = i + length;
331db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            while (i < end) {
332db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                int next = i + BUFFER_LEN;
333e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                appendLocked(buf, i, next < end ? BUFFER_LEN : (end - i));
334db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                i = next;
335db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            }
336db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            return;
337db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
338db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        int pos = mPos;
339db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        if ((pos+length) > BUFFER_LEN) {
340e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            flushLocked();
341db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            pos = mPos;
342db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
343db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        System.arraycopy(buf, i, mText, pos, length);
344db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        mPos = pos + length;
345db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
346db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
347e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    private void flushBytesLocked() throws IOException {
3489b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn        if (!mIoError) {
3499b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn            int position;
3509b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn            if ((position = mBytes.position()) > 0) {
3519b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                mBytes.flip();
3529b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                mOutputStream.write(mBytes.array(), 0, position);
3539b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                mBytes.clear();
3549b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn            }
355db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
356db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
357db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
358e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    private void flushLocked() throws IOException {
359db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        //Log.i("PackageManager", "flush mPos=" + mPos);
360db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        if (mPos > 0) {
361db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            if (mOutputStream != null) {
362db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                CharBuffer charBuffer = CharBuffer.wrap(mText, 0, mPos);
363db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                CoderResult result = mCharset.encode(charBuffer, mBytes, true);
364ce78b9e1146ce204605fb179f10c842644fea61dAndreas Gampe                while (!mIoError) {
365db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                    if (result.isError()) {
366db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                        throw new IOException(result.toString());
367db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                    } else if (result.isOverflow()) {
368e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                        flushBytesLocked();
369db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                        result = mCharset.encode(charBuffer, mBytes, true);
370db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                        continue;
371db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                    }
372db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                    break;
373db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn                }
3749b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                if (!mIoError) {
3759b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                    flushBytesLocked();
3769b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                    mOutputStream.flush();
3779b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                }
3786d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            } else if (mWriter != null) {
3799b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                if (!mIoError) {
3809b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                    mWriter.write(mText, 0, mPos);
3819b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                    mWriter.flush();
3829b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                }
3836d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn            } else {
3846d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                int nonEolOff = 0;
3856d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                final int sepLen = mSeparator.length();
3866d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                final int len = sepLen < mPos ? sepLen : mPos;
3876d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                while (nonEolOff < len && mText[mPos-1-nonEolOff]
3886d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                        == mSeparator.charAt(mSeparator.length()-1-nonEolOff)) {
3896d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                    nonEolOff++;
3906d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                }
3916d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                if (nonEolOff >= mPos) {
3926d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                    mPrinter.println("");
3936d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                } else {
3946d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                    mPrinter.println(new String(mText, 0, mPos-nonEolOff));
3956d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                }
396db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            }
397db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            mPos = 0;
398db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
399db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
400db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
401db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
402db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Ensures that all pending data is sent out to the target. It also
403db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * flushes the target. If an I/O error occurs, this writer's error
404db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * state is set to {@code true}.
405db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
406db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    @Override
407db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public void flush() {
408e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
409e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            try {
410e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                flushLocked();
4119b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                if (!mIoError) {
4129b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                    if (mOutputStream != null) {
4139b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                        mOutputStream.flush();
4149b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                    } else if (mWriter != null) {
4159b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                        mWriter.flush();
4169b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                    }
417e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                }
418e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            } catch (IOException e) {
4199b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                Log.w("FastPrintWriter", "Write failure", e);
420e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                setError();
421e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            }
422e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
423e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    }
424e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn
425e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    @Override
426e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    public void close() {
427e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
428e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            try {
429e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                flushLocked();
430e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                if (mOutputStream != null) {
431e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                    mOutputStream.close();
4326d8dfbd8149942f25f2b9643a12f1fb38f3be834Dianne Hackborn                } else if (mWriter != null) {
433e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                    mWriter.close();
434e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                }
435e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            } catch (IOException e) {
4369b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                Log.w("FastPrintWriter", "Write failure", e);
437e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                setError();
438e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            }
439db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
440db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
441db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
442db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
443db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Prints the string representation of the specified character array
444db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * to the target.
445db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
446db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param charArray
447db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the character array to print to the target.
448db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @see #print(String)
449db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
450db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public void print(char[] charArray) {
451e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
452e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            try {
453e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                appendLocked(charArray, 0, charArray.length);
454e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            } catch (IOException e) {
4559b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                Log.w("FastPrintWriter", "Write failure", e);
4569b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                setError();
457e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            }
458db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
459db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
460db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
461db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
462db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Prints the string representation of the specified character to the
463db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * target.
464db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
465db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param ch
466db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the character to print to the target.
467db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @see #print(String)
468db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
469db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public void print(char ch) {
470e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
471e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            try {
472e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                appendLocked(ch);
473e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            } catch (IOException e) {
4749b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                Log.w("FastPrintWriter", "Write failure", e);
4759b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                setError();
476e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            }
477db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
478db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
479db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
480db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
481db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Prints a string to the target. The string is converted to an array of
482db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * bytes using the encoding chosen during the construction of this writer.
483db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * The bytes are then written to the target with {@code write(int)}.
484db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * <p>
485db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * If an I/O error occurs, this writer's error flag is set to {@code true}.
486db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
487db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param str
488db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the string to print to the target.
489db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @see #write(int)
490db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
491db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public void print(String str) {
492db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        if (str == null) {
493db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            str = String.valueOf((Object) null);
494db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
495e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
496e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            try {
497e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                appendLocked(str, 0, str.length());
498e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            } catch (IOException e) {
4999b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                Log.w("FastPrintWriter", "Write failure", e);
500e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                setError();
501e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            }
502e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
503e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    }
504e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn
505e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn
506e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    @Override
507e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    public void print(int inum) {
508e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        if (inum == 0) {
509e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            print("0");
510e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        } else {
511e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            super.print(inum);
512e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
513e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    }
514e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn
515e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    @Override
516e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    public void print(long lnum) {
517e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        if (lnum == 0) {
518e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            print("0");
519e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        } else {
520e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            super.print(lnum);
521e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
522e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    }
523e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn
524e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    /**
525e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn     * Prints a newline. Flushes this writer if the autoFlush flag is set to {@code true}.
526e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn     */
527e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    public void println() {
528e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
529e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            try {
530e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                appendLocked(mSeparator, 0, mSeparator.length());
531e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                if (mAutoFlush) {
532e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                    flushLocked();
533e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                }
534e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            } catch (IOException e) {
5359b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                Log.w("FastPrintWriter", "Write failure", e);
536e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                setError();
537e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            }
538e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
539e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    }
540e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn
541e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    @Override
542e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    public void println(int inum) {
543e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        if (inum == 0) {
544e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            println("0");
545e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        } else {
546e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            super.println(inum);
547e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        }
548e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    }
549e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn
550e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    @Override
551e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn    public void println(long lnum) {
552e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        if (lnum == 0) {
553e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            println("0");
554e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        } else {
55520cdcee47d10986969e7e2a53a40a6ecabae3827Dianne Hackborn            super.println(lnum);
556db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
557db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
558db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
559db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
560db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Prints the string representation of the character array {@code chars} followed by a newline.
561db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Flushes this writer if the autoFlush flag is set to {@code true}.
562db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
563db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public void println(char[] chars) {
564db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        print(chars);
565db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        println();
566db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
567db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
568db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
569db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Prints the string representation of the char {@code c} followed by a newline.
570db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Flushes this writer if the autoFlush flag is set to {@code true}.
571db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
572db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public void println(char c) {
573db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        print(c);
574db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        println();
575db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
576db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
577db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
578db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Writes {@code count} characters from {@code buffer} starting at {@code
579db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * offset} to the target.
580db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * <p>
581db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * This writer's error flag is set to {@code true} if this writer is closed
582db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * or an I/O error occurs.
583db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
584db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param buf
585db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the buffer to write to the target.
586db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param offset
587db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the index of the first character in {@code buffer} to write.
588db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param count
589db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the number of characters in {@code buffer} to write.
590db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @throws IndexOutOfBoundsException
591db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             if {@code offset < 0} or {@code count < 0}, or if {@code
592db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             offset + count} is greater than the length of {@code buf}.
593db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
594db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    @Override
595db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public void write(char[] buf, int offset, int count) {
596e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
597e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            try {
598e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                appendLocked(buf, offset, count);
599e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            } catch (IOException e) {
6009b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                Log.w("FastPrintWriter", "Write failure", e);
6019b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                setError();
602e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            }
603db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
604db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
605db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
606db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
607db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Writes one character to the target. Only the two least significant bytes
608db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * of the integer {@code oneChar} are written.
609db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * <p>
610db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * This writer's error flag is set to {@code true} if this writer is closed
611db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * or an I/O error occurs.
612db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
613db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param oneChar
614db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the character to write to the target.
615db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
616db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    @Override
617db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public void write(int oneChar) {
618e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
619e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            try {
620e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                appendLocked((char) oneChar);
621e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            } catch (IOException e) {
6229b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                Log.w("FastPrintWriter", "Write failure", e);
6239b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                setError();
624e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            }
625db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
626db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
627db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
628db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
629db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Writes the characters from the specified string to the target.
630db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
631db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param str
632db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the non-null string containing the characters to write.
633db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
634db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    @Override
635db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public void write(String str) {
636e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
637e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            try {
638e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                appendLocked(str, 0, str.length());
639e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            } catch (IOException e) {
6409b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                Log.w("FastPrintWriter", "Write failure", e);
6419b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                setError();
642e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            }
643db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
644db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
645db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
646db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
647db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Writes {@code count} characters from {@code str} starting at {@code
648db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * offset} to the target.
649db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
650db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param str
651db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the non-null string containing the characters to write.
652db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param offset
653db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the index of the first character in {@code str} to write.
654db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param count
655db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the number of characters from {@code str} to write.
656db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @throws IndexOutOfBoundsException
657db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             if {@code offset < 0} or {@code count < 0}, or if {@code
658db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             offset + count} is greater than the length of {@code str}.
659db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
660db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    @Override
661db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public void write(String str, int offset, int count) {
662e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn        synchronized (lock) {
663e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            try {
664e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn                appendLocked(str, offset, count);
665e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            } catch (IOException e) {
6669b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                Log.w("FastPrintWriter", "Write failure", e);
6679b78db41a0f2230001535b3ca33a3ebc31e6c6c1Dianne Hackborn                setError();
668e5a9c92377e035b24f50f9f66f4cdfd9cf79c2ddDianne Hackborn            }
669db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
670db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
671db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn
672db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    /**
673db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * Appends a subsequence of the character sequence {@code csq} to the
674db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * target. This method works the same way as {@code
675db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * PrintWriter.print(csq.subsequence(start, end).toString())}. If {@code
676db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * csq} is {@code null}, then the specified subsequence of the string "null"
677db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * will be written to the target.
678db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *
679db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param csq
680db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the character sequence appended to the target.
681db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param start
682db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the index of the first char in the character sequence appended
683db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            to the target.
684db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @param end
685db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            the index of the character following the last character of the
686db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *            subsequence appended to the target.
687db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @return this writer.
688db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     * @throws StringIndexOutOfBoundsException
689db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             if {@code start > end}, {@code start < 0}, {@code end < 0} or
690db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             either {@code start} or {@code end} are greater or equal than
691db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     *             the length of {@code csq}.
692db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn     */
693db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    @Override
694db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    public PrintWriter append(CharSequence csq, int start, int end) {
695db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        if (csq == null) {
696db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn            csq = "null";
697db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        }
698db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        String output = csq.subSequence(start, end).toString();
699db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        write(output, 0, output.length());
700db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn        return this;
701db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn    }
702db4e33f1f1d766afa3218a6bbdbb561e7962c854Dianne Hackborn}
703