Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2013 Jeanfrancois Arcand
   *
   * Licensed under the Apache License, Version 2.0 (the "License"); you may not
   * use this file except in compliance with the License. You may obtain a copy of
   * the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  * License for the specific language governing permissions and limitations under
  * the License.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package org.atmosphere.wasync.util;
 
 
 import java.io.Reader;
java.io.InputStream implementation that reads a character stream from a java.io.Reader and transforms it to a byte stream using a specified charset encoding. The stream is transformed using a java.nio.charset.CharsetEncoder object, guaranteeing that all charset encodings supported by the JRE are handled correctly. In particular for charsets such as UTF-16, the implementation ensures that one and only one byte order marker is produced.

Since in general it is not possible to predict the number of characters to be read from the java.io.Reader to satisfy a read request on the ReaderInputStream, all reads from the java.io.Reader are buffered. There is therefore no well defined correlation between the current position of the java.io.Reader and that of the ReaderInputStream. This also implies that in general there is no need to wrap the underlying java.io.Reader in a java.io.BufferedReader.

ReaderInputStream implements the inverse transformation of java.io.InputStreamReader; in the following example, reading from in2 would return the same byte sequence as reading from in (provided that the initial byte sequence is legal with respect to the charset encoding):

 InputStream in = ...
 Charset cs = ...
 InputStreamReader reader = new InputStreamReader(in, cs);
 ReaderInputStream in2 = new ReaderInputStream(reader, cs);
ReaderInputStream implements the same transformation as java.io.OutputStreamWriter, except that the control flow is reversed: both classes transform a character stream into a byte stream, but java.io.OutputStreamWriter pushes data to the underlying stream, while ReaderInputStream pulls it from the underlying stream. Note that while there are use cases where there is no alternative to using this class, very often the need to use this class is an indication of a flaw in the design of the code. This class is typically used in situations where an existing API only accepts an java.io.InputStream, but where the most natural way to produce the data is as a character stream, i.e. by providing a java.io.Reader instance. An example of a situation where this problem may appear is when implementing the javax.activation.DataSource interface from the Java Activation Framework. Given the fact that the java.io.Reader class doesn't provide any way to predict whether the next read operation will block or not, it is not possible to provide a meaningful implementation of the java.io.InputStream.available() method. A call to this method will always return 0. Also, this class doesn't support java.io.InputStream.mark(int). Instances of ReaderInputStream are not thread safe.
 
 public class ReaderInputStream extends InputStream {
     private static final int DEFAULT_BUFFER_SIZE = 1024;
 
     private final Reader reader;
     private final CharsetEncoder encoder;

    
CharBuffer used as input for the decoder. It should be reasonably large as we read data from the underlying Reader into this buffer.
 
    private final CharBuffer encoderIn;

    
ByteBuffer used as output for the decoder. This buffer can be small as it is only used to transfer data from the decoder to the buffer provided by the caller.
    private final ByteBuffer encoderOut;
    private CoderResult lastCoderResult;
    private boolean endOfInput;

    
Construct a new ReaderInputStream.

Parameters:
reader the target java.io.Reader
encoder the charset encoder
Since:
2.1
    public ReaderInputStream(Reader readerCharsetEncoder encoder) {
        this(readerencoder);
    }

    
Construct a new ReaderInputStream.

Parameters:
reader the target java.io.Reader
encoder the charset encoder
bufferSize the size of the input buffer in number of characters
Since:
2.1
    public ReaderInputStream(Reader readerCharsetEncoder encoderint bufferSize) {
        this. = reader;
        this. = encoder;
        this. = CharBuffer.allocate(bufferSize);
        this..flip();
        this. = ByteBuffer.allocate(128);
        this..flip();
    }

    
Construct a new ReaderInputStream.

Parameters:
reader the target java.io.Reader
charset the charset encoding
bufferSize the size of the input buffer in number of characters
    public ReaderInputStream(Reader readerCharset charsetint bufferSize) {
        this(reader,
                charset.newEncoder()
                        .onMalformedInput(.)
                        .onUnmappableCharacter(.),
                bufferSize);
    }

    
Construct a new ReaderInputStream with a default input buffer size of 1024 characters.

Parameters:
reader the target java.io.Reader
charset the charset encoding
    public ReaderInputStream(Reader readerCharset charset) {
        this(readercharset);
    }

    
Construct a new ReaderInputStream.

Parameters:
reader the target java.io.Reader
charsetName the name of the charset encoding
bufferSize the size of the input buffer in number of characters
    public ReaderInputStream(Reader readerString charsetNameint bufferSize) {
        this(reader, Charset.forName(charsetName), bufferSize);
    }

    
Construct a new ReaderInputStream with a default input buffer size of 1024 characters.

Parameters:
reader the target java.io.Reader
charsetName the name of the charset encoding
    public ReaderInputStream(Reader readerString charsetName) {
        this(readercharsetName);
    }

    
Construct a new ReaderInputStream that uses the default character encoding with a default input buffer size of 1024 characters.

Parameters:
reader the target java.io.Reader
    public ReaderInputStream(Reader reader) {
        this(reader, Charset.defaultCharset());
    }

    
Fills the internal char buffer from the reader.

Throws:
java.io.IOException If an I/O error occurs
    private void fillBuffer() throws IOException {
        if (! && ( == null || .isUnderflow())) {
            .compact();
            int position = .position();
            // We don't use Reader#read(CharBuffer) here because it is more efficient
            // to write directly to the underlying char array (the default implementation
            // copies data to a temporary char array).
            int c = .read(.array(), position.remaining());
            if (c == -1) {
                 = true;
            } else {
                .position(position + c);
            }
            .flip();
        }
        .compact();
        .flip();
    }

    
Read the specified number of bytes into an array.

Parameters:
b the byte array to read into
off the offset to start reading bytes into
len the number of bytes to read
Returns:
the number of bytes read or -1 if the end of the stream has been reached
Throws:
java.io.IOException if an I/O error occurs
    @Override
    public int read(byte[] bint offint lenthrows IOException {
        if (b == null) {
            throw new NullPointerException("Byte array must not be null");
        }
        if (len < 0 || off < 0 || (off + len) > b.length) {
            throw new IndexOutOfBoundsException("Array Size=" + b.length +
                    ", offset=" + off + ", length=" + len);
        }
        int read = 0;
        if (len == 0) {
            return 0; // Always return 0 if len == 0
        }
        while (len > 0) {
            if (.hasRemaining()) {
                int c = Math.min(.remaining(), len);
                .get(boffc);
                off += c;
                len -= c;
                read += c;
            } else {
                fillBuffer();
                if ( && !.hasRemaining()) {
                    break;
                }
            }
        }
        return read == 0 &&  ? -1 : read;
    }

    
Read the specified number of bytes into an array.

Parameters:
b the byte array to read into
Returns:
the number of bytes read or -1 if the end of the stream has been reached
Throws:
java.io.IOException if an I/O error occurs
    @Override
    public int read(byte[] bthrows IOException {
        return read(b, 0, b.length);
    }

    
Read a single byte.

Returns:
either the byte read or -1 if the end of the stream has been reached
Throws:
java.io.IOException if an I/O error occurs
    @Override
    public int read() throws IOException {
        for (; ; ) {
            if (.hasRemaining()) {
                return .get() & 0xFF;
            } else {
                fillBuffer();
                if ( && !.hasRemaining()) {
                    return -1;
                }
            }
        }
    }

    
Close the stream. This method will cause the underlying java.io.Reader to be closed.

Throws:
java.io.IOException if an I/O error occurs
    @Override
    public void close() throws IOException {
        .close();
    }
New to GrepCode? Check out our FAQ X