/* 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 * @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((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++]; } } }