GwtWorkarounds.java revision 7dd252788645e940eada959bdde927426e2531c9
1/*
2 * Copyright (C) 2012 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14
15package com.google.common.io;
16
17import static com.google.common.base.Preconditions.checkNotNull;
18import static com.google.common.base.Preconditions.checkPositionIndexes;
19
20import com.google.common.annotations.GwtCompatible;
21import com.google.common.annotations.GwtIncompatible;
22
23import java.io.IOException;
24import java.io.InputStream;
25import java.io.OutputStream;
26import java.io.Reader;
27import java.io.Writer;
28
29/**
30 * Provides simple GWT-compatible substitutes for {@code InputStream}, {@code OutputStream},
31 * {@code Reader}, and {@code Writer} so that {@code BaseEncoding} can use streaming implementations
32 * while remaining GWT-compatible.
33 *
34 * @author Louis Wasserman
35 */
36@GwtCompatible(emulated = true)
37final class GwtWorkarounds {
38  private GwtWorkarounds() {}
39
40  /**
41   * A GWT-compatible substitute for a {@code Reader}.
42   */
43  interface CharInput {
44    int read() throws IOException;
45
46    void close() throws IOException;
47  }
48
49  /**
50   * Views a {@code Reader} as a {@code CharInput}.
51   */
52  @GwtIncompatible("Reader")
53  static CharInput asCharInput(final Reader reader) {
54    checkNotNull(reader);
55    return new CharInput() {
56
57      public int read() throws IOException {
58        return reader.read();
59      }
60
61      public void close() throws IOException {
62        reader.close();
63      }
64    };
65  }
66
67  /**
68   * Views a {@code CharSequence} as a {@code CharInput}.
69   */
70  static CharInput asCharInput(final CharSequence chars) {
71    checkNotNull(chars);
72    return new CharInput() {
73      int index = 0;
74
75      public int read() {
76        if (index < chars.length()) {
77          return chars.charAt(index++);
78        } else {
79          return -1;
80        }
81      }
82
83      public void close() {
84        index = chars.length();
85      }
86    };
87  }
88
89  /**
90   * A GWT-compatible substitute for an {@code InputStream}.
91   */
92  interface ByteInput {
93    int read() throws IOException;
94
95    void close() throws IOException;
96  }
97
98  /**
99   * Views a {@code ByteInput} as an {@code InputStream}.
100   */
101  @GwtIncompatible("InputStream")
102  static InputStream asInputStream(final ByteInput input) {
103    checkNotNull(input);
104    return new InputStream() {
105
106      @Override
107      public int read() throws IOException {
108        return input.read();
109      }
110
111      @Override
112      public int read(byte[] b, int off, int len) throws IOException {
113        checkNotNull(b);
114        checkPositionIndexes(off, off + len, b.length);
115        if (len == 0) {
116          return 0;
117        }
118        int firstByte = read();
119        if (firstByte == -1) {
120          return -1;
121        }
122        b[off] = (byte) firstByte;
123        for (int dst = 1; dst < len; dst++) {
124          int readByte = read();
125          if (readByte == -1) {
126            return dst;
127          }
128          b[off + dst] = (byte) readByte;
129        }
130        return len;
131      }
132
133      @Override
134      public void close() throws IOException {
135        input.close();
136      }
137    };
138  }
139
140  /**
141   * A GWT-compatible substitute for an {@code OutputStream}.
142   */
143  interface ByteOutput {
144    void write(byte b) throws IOException;
145
146    void flush() throws IOException;
147
148    void close() throws IOException;
149  }
150
151  /**
152   * Views a {@code ByteOutput} as an {@code OutputStream}.
153   */
154  @GwtIncompatible("OutputStream")
155  static OutputStream asOutputStream(final ByteOutput output) {
156    checkNotNull(output);
157    return new OutputStream() {
158
159      @Override
160      public void write(int b) throws IOException {
161        output.write((byte) b);
162      }
163
164      @Override
165      public void flush() throws IOException {
166        output.flush();
167      }
168
169      @Override
170      public void close() throws IOException {
171        output.close();
172      }
173    };
174  }
175
176  /**
177   * A GWT-compatible substitute for a {@code Writer}.
178   */
179  interface CharOutput {
180    void write(char c) throws IOException;
181
182    void flush() throws IOException;
183
184    void close() throws IOException;
185  }
186
187  /**
188   * Views a {@code Writer} as a {@code CharOutput}.
189   */
190  @GwtIncompatible("Writer")
191  static CharOutput asCharOutput(final Writer writer) {
192    checkNotNull(writer);
193    return new CharOutput() {
194
195      public void write(char c) throws IOException {
196        writer.append(c);
197      }
198
199      public void flush() throws IOException {
200        writer.flush();
201      }
202
203      public void close() throws IOException {
204        writer.close();
205      }
206    };
207  }
208
209  /**
210   * Returns a {@code CharOutput} whose {@code toString()} method can be used
211   * to get the combined output.
212   */
213  static CharOutput stringBuilderOutput(int initialSize) {
214    final StringBuilder builder = new StringBuilder(initialSize);
215    return new CharOutput() {
216
217      public void write(char c) {
218        builder.append(c);
219      }
220
221      public void flush() {}
222
223      public void close() {}
224
225      @Override
226      public String toString() {
227        return builder.toString();
228      }
229    };
230  }
231}
232