19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.os;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
20f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilsonimport java.io.OutputStream;
21f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilsonimport java.io.PrintStream;
22f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilsonimport java.nio.ByteBuffer;
23f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilsonimport java.nio.CharBuffer;
24f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilsonimport java.nio.charset.Charset;
25f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilsonimport java.nio.charset.CharsetDecoder;
26f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilsonimport java.nio.charset.CoderResult;
27f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilsonimport java.nio.charset.CodingErrorAction;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Formatter;
29f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilsonimport java.util.Locale;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A print stream which logs output line by line.
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide}
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectabstract class LoggingPrintStream extends PrintStream {
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final StringBuilder builder = new StringBuilder();
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
40f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    /**
41f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     * A buffer that is initialized when raw bytes are first written to this
42f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     * stream. It may contain the leading bytes of multi-byte characters.
43f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     * Between writes this buffer is always ready to receive data; ie. the
44f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     * position is at the first unassigned byte and the limit is the capacity.
45f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     */
46f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    private ByteBuffer encodedBytes;
47f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson
48f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    /**
49f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     * A buffer that is initialized when raw bytes are first written to this
50f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     * stream. Between writes this buffer is always clear; ie. the position is
51f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     * zero and the limit is the capacity.
52f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     */
53f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    private CharBuffer decodedChars;
54f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson
55f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    /**
56f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     * Decodes bytes to characters using the system default charset. Initialized
57f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     * when raw bytes are first written to this stream.
58f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson     */
59f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    private CharsetDecoder decoder;
60f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected LoggingPrintStream() {
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super(new OutputStream() {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void write(int oneByte) throws IOException {
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new AssertionError();
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        });
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Logs the given line.
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected abstract void log(String line);
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void flush() {
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(true);
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Searches buffer for line breaks and logs a message for each one.
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param completely true if the ending chars should be treated as a line
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  even though they don't end in a line break
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private void flush(boolean completely) {
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int length = builder.length();
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int start = 0;
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int nextBreak;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Log one line for each line break.
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (start < length
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && (nextBreak = builder.indexOf("\n", start)) != -1) {
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            log(builder.substring(start, nextBreak));
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            start = nextBreak + 1;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (completely) {
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Log the remainder of the buffer.
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (start < length) {
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                log(builder.substring(start));
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            builder.setLength(0);
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Delete characters leading up to the next starting point.
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            builder.delete(0, start);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
110f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    public void write(int oneByte) {
111f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson        write(new byte[] { (byte) oneByte }, 0, 1);
112f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    }
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
115f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    public void write(byte[] buffer) {
116f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson        write(buffer, 0, buffer.length);
117f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
120f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    public synchronized void write(byte bytes[], int start, int count) {
121f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson        if (decoder == null) {
122f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            encodedBytes = ByteBuffer.allocate(80);
123f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            decodedChars = CharBuffer.allocate(80);
124f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            decoder = Charset.defaultCharset().newDecoder()
125f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson                    .onMalformedInput(CodingErrorAction.REPLACE)
126f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson                    .onUnmappableCharacter(CodingErrorAction.REPLACE);
127f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson        }
128f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson
129f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson        int end = start + count;
130f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson        while (start < end) {
131f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            // copy some bytes from the array to the long-lived buffer. This
132f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            // way, if we end with a partial character we don't lose it.
133f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            int numBytes = Math.min(encodedBytes.remaining(), end - start);
134f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            encodedBytes.put(bytes, start, numBytes);
135f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            start += numBytes;
136f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson
137f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            encodedBytes.flip();
138f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            CoderResult coderResult;
139f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            do {
140f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson                // decode bytes from the byte buffer into the char buffer
141f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson                coderResult = decoder.decode(encodedBytes, decodedChars, false);
142f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson
143f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson                // copy chars from the char buffer into our string builder
144f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson                decodedChars.flip();
145f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson                builder.append(decodedChars);
146f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson                decodedChars.clear();
147f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            } while (coderResult.isOverflow());
148f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson            encodedBytes.compact();
149f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson        }
150f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson        flush(false);
151f41de2a4a1c22e3f3ee9a8cd65ec7997c9587cdbJesse Wilson    }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Always returns false. */
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean checkError() {
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Ignored. */
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void setError() { /* ignored */ }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Ignored. */
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void close() { /* ignored */ }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PrintStream format(String format, Object... args) {
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return format(Locale.getDefault(), format, args);
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PrintStream printf(String format, Object... args) {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return format(format, args);
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public PrintStream printf(Locale l, String format, Object... args) {
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return format(l, format, args);
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Formatter formatter = new Formatter(builder, null);
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized PrintStream format(
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Locale l, String format, Object... args) {
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (format == null) {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NullPointerException("format");
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        formatter.format(l, format, args);
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(false);
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void print(char[] charArray) {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(charArray);
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(false);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void print(char ch) {
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(ch);
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ch == '\n') {
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flush(false);
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void print(double dnum) {
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(dnum);
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void print(float fnum) {
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(fnum);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void print(int inum) {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(inum);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void print(long lnum) {
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(lnum);
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void print(Object obj) {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(obj);
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(false);
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void print(String str) {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(str);
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(false);
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void print(boolean bool) {
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(bool);
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void println() {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(true);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void println(char[] charArray) {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(charArray);
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(true);
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void println(char ch) {
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(ch);
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(true);
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void println(double dnum) {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(dnum);
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(true);
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void println(float fnum) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(fnum);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(true);
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void println(int inum) {
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(inum);
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(true);
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void println(long lnum) {
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(lnum);
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(true);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void println(Object obj) {
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(obj);
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(true);
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void println(String s) {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (builder.length() == 0) {
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Optimization for a simple println.
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int length = s.length();
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int start = 0;
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int nextBreak;
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Log one line for each line break.
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (start < length
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    && (nextBreak = s.indexOf('\n', start)) != -1) {
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                log(s.substring(start, nextBreak));
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                start = nextBreak + 1;
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (start < length) {
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                log(s.substring(start));
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            builder.append(s);
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flush(true);
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void println(boolean bool) {
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(bool);
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(true);
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized PrintStream append(char c) {
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        print(c);
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized PrintStream append(CharSequence csq) {
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(csq);
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(false);
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized PrintStream append(
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            CharSequence csq, int start, int end) {
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.append(csq, start, end);
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        flush(false);
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
346