diff options
Diffstat (limited to 'libjava/java/io/InputStreamReader.java')
-rw-r--r-- | libjava/java/io/InputStreamReader.java | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/libjava/java/io/InputStreamReader.java b/libjava/java/io/InputStreamReader.java new file mode 100644 index 0000000..ee44f91 --- /dev/null +++ b/libjava/java/io/InputStreamReader.java @@ -0,0 +1,151 @@ +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +package java.io; +import gnu.gcj.convert.*; + +/** + * @author Per Bothner <bothner@cygnus.com> + * @date April 22, 1998. + */ +/* Written using "Java Class Libraries", 2nd edition, plus online + * API docs for JDK 1.2 beta from http://www.javasoft.com. + * Status: Believed complete and correct, but only supports 8859_1. + */ + +public class InputStreamReader extends Reader +{ + BufferedInputStream in; + + // Buffer of chars read from in and converted but not consumed. + char[] work; + // Next available character (in work buffer) to read. + int wpos; + // Last available character (in work buffer) to read. + int wcount; + + BytesToUnicode converter; + + public InputStreamReader(InputStream in) + { + this(in, BytesToUnicode.getDefaultDecoder()); + } + + public InputStreamReader(InputStream in, String enc) + throws UnsupportedEncodingException + { + this(in, BytesToUnicode.getDecoder(enc)); + } + + private InputStreamReader(InputStream in, BytesToUnicode decoder) + { + super(in); + this.in = in instanceof BufferedInputStream ? (BufferedInputStream) in + : new BufferedInputStream(in, 250); + converter = decoder; + converter.setInput(this.in.buf, 0, 0); + } + + public void close() throws IOException + { + synchronized (lock) + { + if (in != null) + in.close(); + in = null; + work = null; + wpos = wcount = 0; + } + } + + public String getEncoding() { return converter.getName(); } + + public boolean ready() throws IOException + { + synchronized (lock) + { + if (wpos < wcount) + return true; + if (work == null) + { + work = new char[100]; + wpos = 0; + wcount = 0; + } + for (;;) + { + if (in.available() <= 0) + return false; + in.mark(1); + int b = in.read(); + if (b < 0) + return true; + in.reset(); + converter.setInput(in.buf, in.pos, in.count); + wpos = 0; + wcount = converter.read(work, 0, work.length); + in.skip(converter.inpos - in.pos); + if (wcount > 0) + return true; + } + } + } + + public int read(char buf[], int offset, int length) throws IOException + { + synchronized (lock) + { + int wavail = wcount - wpos; + if (wavail > 0) + { + if (length > wavail) + length = wavail; + System.arraycopy(work, wpos, buf, offset, length); + wpos += length; + return length; + } + else + { + for (;;) + { + in.mark(1); + int b = in.read(); + if (b < 0) + return -1; + in.reset(); + converter.setInput(in.buf, in.pos, in.count); + int count = converter.read (buf, offset, length); + in.skip(converter.inpos - in.pos); + if (count > 0) + return count; + } + } + } + } + + public int read() throws IOException + { + synchronized (lock) + { + int wavail = wcount - wpos; + if (wavail > 0) + return work[wpos++]; + if (work == null) + { + work = new char[100]; + wpos = 0; + wcount = 0; + } + int count = read(work, wpos, work.length-wpos); + if (count <= 0) + return -1; + wcount = wpos + count; + return work[wpos++]; + } + } +} |