1bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors
3bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
4bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Licensed under the Apache License, Version 2.0 (the "License");
5bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * you may not use this file except in compliance with the License.
6bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * You may obtain a copy of the License at
7bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
8bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * http://www.apache.org/licenses/LICENSE-2.0
9bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
10bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Unless required by applicable law or agreed to in writing, software
11bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * distributed under the License is distributed on an "AS IS" BASIS,
12bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * See the License for the specific language governing permissions and
14bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * limitations under the License.
15bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */
16bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
17bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpackage com.google.common.io;
18bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
197dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkNotNull;
200888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport static com.google.common.base.Preconditions.checkPositionIndexes;
217dd252788645e940eada959bdde927426e2531c9Paul Duffin
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta;
23bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
24bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.Closeable;
25bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.EOFException;
26bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.IOException;
27bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.Reader;
28bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.Writer;
29bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.nio.CharBuffer;
30bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.ArrayList;
31bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.List;
32bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
33bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/**
34bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Provides utility methods for working with character streams.
35bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
36bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>All method parameters must be non-null unless documented otherwise.
37bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
38bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * <p>Some of the methods in this class take arguments with a generic type of
39bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@code Readable & Closeable}. A {@link java.io.Reader} implements both of
40bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * those interfaces. Similarly for {@code Appendable & Closeable} and
41bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * {@link java.io.Writer}.
42bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
43bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @author Chris Nokleberg
44bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @author Bin Zhu
457dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Colin Decker
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 1.0
47bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta
49bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic final class CharStreams {
50bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private static final int BUF_SIZE = 0x800; // 2K chars (4K bytes)
51bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
52bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private CharStreams() {}
53bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
54bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
55bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Copies all characters between the {@link Readable} and {@link Appendable}
56bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * objects. Does not close or flush either object.
57bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
58bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param from the object to read from
59bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param to the object to write to
60bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return the number of characters copied
61bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws IOException if an I/O error occurs
62bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
63bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static long copy(Readable from, Appendable to) throws IOException {
647dd252788645e940eada959bdde927426e2531c9Paul Duffin    checkNotNull(from);
657dd252788645e940eada959bdde927426e2531c9Paul Duffin    checkNotNull(to);
66bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    CharBuffer buf = CharBuffer.allocate(BUF_SIZE);
67bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    long total = 0;
687dd252788645e940eada959bdde927426e2531c9Paul Duffin    while (from.read(buf) != -1) {
69bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      buf.flip();
707dd252788645e940eada959bdde927426e2531c9Paul Duffin      to.append(buf);
717dd252788645e940eada959bdde927426e2531c9Paul Duffin      total += buf.remaining();
727dd252788645e940eada959bdde927426e2531c9Paul Duffin      buf.clear();
73bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
74bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return total;
75bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
76bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
77bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
78bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Reads all characters from a {@link Readable} object into a {@link String}.
79bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Does not close the {@code Readable}.
80bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
81bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param r the object to read from
82bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return a string containing all the characters
83bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws IOException if an I/O error occurs
84bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
85bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static String toString(Readable r) throws IOException {
86bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return toStringBuilder(r).toString();
87bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
88bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
89bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
90bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Reads all characters from a {@link Readable} object into a new
91bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * {@link StringBuilder} instance. Does not close the {@code Readable}.
92bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
93bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param r the object to read from
94bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return a {@link StringBuilder} containing all the characters
95bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws IOException if an I/O error occurs
96bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
97bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private static StringBuilder toStringBuilder(Readable r) throws IOException {
98bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    StringBuilder sb = new StringBuilder();
99bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    copy(r, sb);
100bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return sb;
101bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
102bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
103bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
104bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Reads all of the lines from a {@link Readable} object. The lines do
105bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * not include line-termination characters, but do include other
106bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * leading and trailing whitespace.
107bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
108bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * <p>Does not close the {@code Readable}. If reading files or resources you
109bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * should use the {@link Files#readLines} and {@link Resources#readLines}
110bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * methods.
111bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
112bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param r the object to read from
113bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return a mutable {@link List} containing all the lines
114bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws IOException if an I/O error occurs
115bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
116bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static List<String> readLines(Readable r) throws IOException {
117bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    List<String> result = new ArrayList<String>();
118bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    LineReader lineReader = new LineReader(r);
119bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    String line;
120bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    while ((line = lineReader.readLine()) != null) {
121bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      result.add(line);
122bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
123bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return result;
124bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
125bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
126bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
1277dd252788645e940eada959bdde927426e2531c9Paul Duffin   * Streams lines from a {@link Readable} object, stopping when the processor
1287dd252788645e940eada959bdde927426e2531c9Paul Duffin   * returns {@code false} or all lines have been read and returning the result
1297dd252788645e940eada959bdde927426e2531c9Paul Duffin   * produced by the processor. Does not close {@code readable}. Note that this
1307dd252788645e940eada959bdde927426e2531c9Paul Duffin   * method may not fully consume the contents of {@code readable} if the
1317dd252788645e940eada959bdde927426e2531c9Paul Duffin   * processor stops processing early.
1327dd252788645e940eada959bdde927426e2531c9Paul Duffin   *
1337dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @throws IOException if an I/O error occurs
1347dd252788645e940eada959bdde927426e2531c9Paul Duffin   * @since 14.0
1357dd252788645e940eada959bdde927426e2531c9Paul Duffin   */
1360888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static <T> T readLines(
1370888a09821a98ac0680fad765217302858e70fa4Paul Duffin      Readable readable, LineProcessor<T> processor) throws IOException {
1387dd252788645e940eada959bdde927426e2531c9Paul Duffin    checkNotNull(readable);
1397dd252788645e940eada959bdde927426e2531c9Paul Duffin    checkNotNull(processor);
1407dd252788645e940eada959bdde927426e2531c9Paul Duffin
1417dd252788645e940eada959bdde927426e2531c9Paul Duffin    LineReader lineReader = new LineReader(readable);
1427dd252788645e940eada959bdde927426e2531c9Paul Duffin    String line;
1437dd252788645e940eada959bdde927426e2531c9Paul Duffin    while ((line = lineReader.readLine()) != null) {
1447dd252788645e940eada959bdde927426e2531c9Paul Duffin      if (!processor.processLine(line)) {
1457dd252788645e940eada959bdde927426e2531c9Paul Duffin        break;
1467dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
1477dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
1487dd252788645e940eada959bdde927426e2531c9Paul Duffin    return processor.getResult();
1497dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
1507dd252788645e940eada959bdde927426e2531c9Paul Duffin
1517dd252788645e940eada959bdde927426e2531c9Paul Duffin  /**
152bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Discards {@code n} characters of data from the reader. This method
153bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * will block until the full amount has been skipped. Does not close the
154bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * reader.
155bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
156bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param reader the reader to read from
157bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param n the number of characters to skip
158bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws EOFException if this stream reaches the end before skipping all
1590888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *     the characters
160bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws IOException if an I/O error occurs
161bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
162bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static void skipFully(Reader reader, long n) throws IOException {
1637dd252788645e940eada959bdde927426e2531c9Paul Duffin    checkNotNull(reader);
164bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    while (n > 0) {
165bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      long amt = reader.skip(n);
166bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (amt == 0) {
167bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        // force a blocking read
168bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        if (reader.read() == -1) {
169bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          throw new EOFException();
170bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        }
171bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        n--;
172bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      } else {
173bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        n -= amt;
174bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
175bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
176bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
177bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
178bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
1790888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * Returns a {@link Writer} that simply discards written chars.
1800888a09821a98ac0680fad765217302858e70fa4Paul Duffin   *
1810888a09821a98ac0680fad765217302858e70fa4Paul Duffin   * @since 15.0
1820888a09821a98ac0680fad765217302858e70fa4Paul Duffin   */
1830888a09821a98ac0680fad765217302858e70fa4Paul Duffin  public static Writer nullWriter() {
1840888a09821a98ac0680fad765217302858e70fa4Paul Duffin    return NullWriter.INSTANCE;
1850888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
1860888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1870888a09821a98ac0680fad765217302858e70fa4Paul Duffin  private static final class NullWriter extends Writer {
1880888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1890888a09821a98ac0680fad765217302858e70fa4Paul Duffin    private static final NullWriter INSTANCE = new NullWriter();
1900888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1910888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1920888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public void write(int c) {
1930888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1940888a09821a98ac0680fad765217302858e70fa4Paul Duffin
1950888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
1960888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public void write(char[] cbuf) {
1970888a09821a98ac0680fad765217302858e70fa4Paul Duffin      checkNotNull(cbuf);
1980888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
1990888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2000888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2010888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public void write(char[] cbuf, int off, int len) {
2020888a09821a98ac0680fad765217302858e70fa4Paul Duffin      checkPositionIndexes(off, off + len, cbuf.length);
2030888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2040888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2050888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2060888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public void write(String str) {
2070888a09821a98ac0680fad765217302858e70fa4Paul Duffin      checkNotNull(str);
2080888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2090888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2100888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2110888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public void write(String str, int off, int len) {
2120888a09821a98ac0680fad765217302858e70fa4Paul Duffin      checkPositionIndexes(off, off + len, str.length());
2130888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2140888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2150888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2160888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public Writer append(CharSequence csq) {
2170888a09821a98ac0680fad765217302858e70fa4Paul Duffin      checkNotNull(csq);
2180888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return this;
2190888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2200888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2210888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2220888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public Writer append(CharSequence csq, int start, int end) {
2230888a09821a98ac0680fad765217302858e70fa4Paul Duffin      checkPositionIndexes(start, end, csq.length());
2240888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return this;
2250888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2260888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2270888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2280888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public Writer append(char c) {
2290888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return this;
2300888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2310888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2320888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2330888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public void flush() {
2340888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2350888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2360888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2370888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public void close() {
2380888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2390888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2400888a09821a98ac0680fad765217302858e70fa4Paul Duffin    @Override
2410888a09821a98ac0680fad765217302858e70fa4Paul Duffin    public String toString() {
2420888a09821a98ac0680fad765217302858e70fa4Paul Duffin      return "CharStreams.nullWriter()";
2430888a09821a98ac0680fad765217302858e70fa4Paul Duffin    }
2440888a09821a98ac0680fad765217302858e70fa4Paul Duffin  }
2450888a09821a98ac0680fad765217302858e70fa4Paul Duffin
2460888a09821a98ac0680fad765217302858e70fa4Paul Duffin  /**
247bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns a Writer that sends all output to the given {@link Appendable}
248bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * target. Closing the writer will close the target if it is {@link
249bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Closeable}, and flushing the writer will flush the target if it is {@link
250bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * java.io.Flushable}.
251bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
252bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param target the object to which output will be sent
253bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return a new Writer object, unless target is a Writer, in which case the
254bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     target is returned
255bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
256bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static Writer asWriter(Appendable target) {
257bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    if (target instanceof Writer) {
258bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return (Writer) target;
259bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
260bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return new AppendableWriter(target);
261bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
2627dd252788645e940eada959bdde927426e2531c9Paul Duffin
2637dd252788645e940eada959bdde927426e2531c9Paul Duffin  // TODO(user): Remove these once Input/OutputSupplier methods are removed
2647dd252788645e940eada959bdde927426e2531c9Paul Duffin
2650888a09821a98ac0680fad765217302858e70fa4Paul Duffin  static Reader asReader(final Readable readable) {
2667dd252788645e940eada959bdde927426e2531c9Paul Duffin    checkNotNull(readable);
2677dd252788645e940eada959bdde927426e2531c9Paul Duffin    if (readable instanceof Reader) {
2687dd252788645e940eada959bdde927426e2531c9Paul Duffin      return (Reader) readable;
2697dd252788645e940eada959bdde927426e2531c9Paul Duffin    }
2707dd252788645e940eada959bdde927426e2531c9Paul Duffin    return new Reader() {
2717dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
2727dd252788645e940eada959bdde927426e2531c9Paul Duffin      public int read(char[] cbuf, int off, int len) throws IOException {
2737dd252788645e940eada959bdde927426e2531c9Paul Duffin        return read(CharBuffer.wrap(cbuf, off, len));
2747dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
2757dd252788645e940eada959bdde927426e2531c9Paul Duffin
2767dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
2777dd252788645e940eada959bdde927426e2531c9Paul Duffin      public int read(CharBuffer target) throws IOException {
2787dd252788645e940eada959bdde927426e2531c9Paul Duffin        return readable.read(target);
2797dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
2807dd252788645e940eada959bdde927426e2531c9Paul Duffin
2817dd252788645e940eada959bdde927426e2531c9Paul Duffin      @Override
2827dd252788645e940eada959bdde927426e2531c9Paul Duffin      public void close() throws IOException {
2830888a09821a98ac0680fad765217302858e70fa4Paul Duffin        if (readable instanceof Closeable) {
2840888a09821a98ac0680fad765217302858e70fa4Paul Duffin          ((Closeable) readable).close();
2850888a09821a98ac0680fad765217302858e70fa4Paul Duffin        }
2867dd252788645e940eada959bdde927426e2531c9Paul Duffin      }
2877dd252788645e940eada959bdde927426e2531c9Paul Duffin    };
2887dd252788645e940eada959bdde927426e2531c9Paul Duffin  }
289bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor}
290