source: trunk/src/gcc/libjava/java/io/InputStreamReader.java@ 2

Last change on this file since 2 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 3.9 KB
Line 
1/* Copyright (C) 1998, 1999, 2001 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 <[email protected]>
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() { return converter.getName(); }
74
75 public boolean ready() throws IOException
76 {
77 synchronized (lock)
78 {
79 if (in == null)
80 throw new IOException("Stream closed");
81
82 if (wpos < wcount)
83 return true;
84
85 // According to the spec, an InputStreamReader is ready if its
86 // input buffer is not empty (above), or if bytes are
87 // available on the underlying byte stream.
88 return in.available () > 0;
89 }
90 }
91
92 public int read(char buf[], int offset, int length) throws IOException
93 {
94 synchronized (lock)
95 {
96 if (in == null)
97 throw new IOException("Stream closed");
98
99 if (length == 0)
100 return 0;
101
102 int wavail = wcount - wpos;
103 if (wavail <= 0)
104 {
105 // Nothing waiting, so refill our buffer.
106 if (! refill ())
107 return -1;
108 wavail = wcount - wpos;
109 }
110
111 if (length > wavail)
112 length = wavail;
113 System.arraycopy(work, wpos, buf, offset, length);
114 wpos += length;
115 return length;
116 }
117 }
118
119 public int read() throws IOException
120 {
121 synchronized (lock)
122 {
123 if (in == null)
124 throw new IOException("Stream closed");
125
126 int wavail = wcount - wpos;
127 if (wavail <= 0)
128 {
129 // Nothing waiting, so refill our buffer.
130 if (! refill ())
131 return -1;
132 }
133
134 return work[wpos++];
135 }
136 }
137
138 // Read more bytes and convert them into the WORK buffer.
139 // Return false on EOF.
140 private boolean refill () throws IOException
141 {
142 wcount = wpos = 0;
143
144 if (work == null)
145 work = new char[100];
146
147 for (;;)
148 {
149 // We have knowledge of the internals of BufferedInputStream
150 // here. Eww.
151 in.mark (0);
152 // BufferedInputStream.refill() can only be called when
153 // `pos>=count'.
154 boolean r = in.pos < in.count || in.refill ();
155 in.reset ();
156 if (! r)
157 return false;
158 converter.setInput(in.buf, in.pos, in.count);
159 int count = converter.read (work, wpos, work.length - wpos);
160 in.skip(converter.inpos - in.pos);
161 if (count > 0)
162 {
163 wcount += count;
164 return true;
165 }
166 }
167 }
168}
Note: See TracBrowser for help on using the repository browser.