source: trunk/gcc/libjava/java/io/InputStreamReader.java

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 3.9 KB
Line 
1/* Copyright (C) 1998, 1999, 2001, 2003 Free Software Foundation
2
3 This file is part of libgcj.
4
5This software is copyrighted work licensed under the terms of the
6Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
7details. */
8
9package java.io;
10import gnu.gcj.convert.*;
11
12/**
13 * @author Per Bothner <bothner@cygnus.com>
14 * @date April 22, 1998.
15 */
16/* Written using "Java Class Libraries", 2nd edition, plus online
17 * API docs for JDK 1.2 beta from http://www.javasoft.com.
18 * Status: Believed complete and correct, but only supports 8859_1.
19 */
20
21public class InputStreamReader extends Reader
22{
23 BufferedInputStream in;
24
25 // Buffer of chars read from in and converted but not consumed.
26 char[] work;
27 // Next available character (in work buffer) to read.
28 int wpos;
29 // Last available character (in work buffer) to read.
30 int wcount;
31
32 BytesToUnicode converter;
33
34 public InputStreamReader(InputStream in)
35 {
36 this(in, BytesToUnicode.getDefaultDecoder());
37 }
38
39 public InputStreamReader(InputStream in, String enc)
40 throws UnsupportedEncodingException
41 {
42 this(in, BytesToUnicode.getDecoder(enc));
43 }
44
45 private InputStreamReader(InputStream in, BytesToUnicode decoder)
46 {
47 // FIXME: someone could pass in a BufferedInputStream whose buffer
48 // is smaller than the longest encoded character for this
49 // encoding. We will probably go into an infinite loop in this
50 // case. We probably ought to just have our own byte buffering
51 // here.
52 this.in = in instanceof BufferedInputStream
53 ? (BufferedInputStream) in
54 : new BufferedInputStream(in);
55 /* Don't need to call super(in) here as long as the lock gets set. */
56 this.lock = in;
57 converter = decoder;
58 converter.setInput(this.in.buf, 0, 0);
59 }
60
61 public void close() throws IOException
62 {
63 synchronized (lock)
64 {
65 if (in != null)
66 in.close();
67 in = null;
68 work = null;
69 wpos = wcount = 0;
70 }
71 }
72
73 public String getEncoding()
74 {
75 return in != null ? converter.getName() : null;
76 }
77
78 public boolean ready() throws IOException
79 {
80 synchronized (lock)
81 {
82 if (in == null)
83 throw new IOException("Stream closed");
84
85 if (wpos < wcount)
86 return true;
87
88 // According to the spec, an InputStreamReader is ready if its
89 // input buffer is not empty (above), or if bytes are
90 // available on the underlying byte stream.
91 return in.available () > 0;
92 }
93 }
94
95 public int read(char buf[], int offset, int length) throws IOException
96 {
97 synchronized (lock)
98 {
99 if (in == null)
100 throw new IOException("Stream closed");
101
102 if (length == 0)
103 return 0;
104
105 int wavail = wcount - wpos;
106 if (wavail <= 0)
107 {
108 // Nothing waiting, so refill our buffer.
109 if (! refill ())
110 return -1;
111 wavail = wcount - wpos;
112 }
113
114 if (length > wavail)
115 length = wavail;
116 System.arraycopy(work, wpos, buf, offset, length);
117 wpos += length;
118 return length;
119 }
120 }
121
122 public int read() throws IOException
123 {
124 synchronized (lock)
125 {
126 if (in == null)
127 throw new IOException("Stream closed");
128
129 int wavail = wcount - wpos;
130 if (wavail <= 0)
131 {
132 // Nothing waiting, so refill our buffer.
133 if (! refill ())
134 return -1;
135 }
136
137 return work[wpos++];
138 }
139 }
140
141 // Read more bytes and convert them into the WORK buffer.
142 // Return false on EOF.
143 private boolean refill () throws IOException
144 {
145 wcount = wpos = 0;
146
147 if (work == null)
148 work = new char[100];
149
150 for (;;)
151 {
152 // We have knowledge of the internals of BufferedInputStream
153 // here. Eww.
154 in.mark (0);
155 // BufferedInputStream.refill() can only be called when
156 // `pos>=count'.
157 boolean r = in.pos < in.count || in.refill ();
158 in.reset ();
159 if (! r)
160 return false;
161 converter.setInput(in.buf, in.pos, in.count);
162 int count = converter.read (work, wpos, work.length - wpos);
163 in.skip(converter.inpos - in.pos);
164 if (count > 0)
165 {
166 wcount += count;
167 return true;
168 }
169 }
170 }
171}
Note: See TracBrowser for help on using the repository browser.