/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
/**
* @author Enrico Persiani
*/
public class ReaderInputStream extends InputStream {
private final Reader reader;
private CharsetEncoder encoder;
private boolean endOfInput;
private CharBuffer in;
public ReaderInputStream(Reader reader) {
this(reader, Charset.defaultCharset().name());
}
public ReaderInputStream(Reader reader, String encoding) {
this(reader, Charset.forName(encoding));
}
public ReaderInputStream(Reader reader, Charset charset) {
this(reader, charset, 32);
}
public ReaderInputStream(Reader reader, Charset charset, int size) {
this.reader = reader;
this.encoder = charset.newEncoder();
this.endOfInput = false;
this.in = CharBuffer.allocate(size);
this.in.limit(0);
}
@Override
public int read() throws IOException {
byte[] b = new byte[1];
return read(b) == -1 ? -1 : b[0] & 0x000000FF;
}
@Override
public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
// fill input buffer as much as possible
if (!endOfInput) {
in.compact();
endOfInput = reader.read(in) == -1;
in.flip();
}
// encode to the wrapped buffer
ByteBuffer out = ByteBuffer.wrap(b, off, len);
if (encoder.encode(in, out, endOfInput).isError())
throw new IOException("encoding error");
if (!in.hasRemaining())
in.clear().limit(0);
int count = out.position() - off;
return count > 0 ? count : -1;
}
@Override
public void close() throws IOException {
reader.close();
}
}