Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: gnu/xml/dom/ls/ReaderInputStream.java


1   /* ReaderInputStream.java -- 
2      Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
3   
4   This file is part of GNU Classpath.
5   
6   GNU Classpath is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10  
11  GNU Classpath is distributed in the hope that it will be useful, but
12  WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  General Public License for more details.
15  
16  You should have received a copy of the GNU General Public License
17  along with GNU Classpath; see the file COPYING.  If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301 USA.
20  
21  Linking this library statically or dynamically with other modules is
22  making a combined work based on this library.  Thus, the terms and
23  conditions of the GNU General Public License cover the whole
24  combination.
25  
26  As a special exception, the copyright holders of this library give you
27  permission to link this library with independent modules to produce an
28  executable, regardless of the license terms of these independent
29  modules, and to copy and distribute the resulting executable under
30  terms of your choice, provided that you also meet, for each linked
31  independent module, the terms and conditions of the license of that
32  module.  An independent module is a module which is not derived from
33  or based on this library.  If you modify this library, you may extend
34  this exception to your version of the library, but you are not
35  obligated to do so.  If you do not wish to do so, delete this
36  exception statement from your version. */
37  
38  package gnu.xml.dom.ls;
39  
40  import java.io.InputStream;
41  import java.io.IOException;
42  import java.io.Reader;
43  
44  /**
45   * Character stream wrapper.
46   *
47   * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
48   * @author <a href='mailto:mark@klomp.org'>Mark Wielaard</a>
49   */
50  public class ReaderInputStream
51    extends InputStream
52  {
53  
54    private Reader reader;
55    private String encoding;
56  
57    // Holds extra spillover data if necessary
58    private byte extra[];
59    private int pos;
60  
61    private byte extra_marked[];
62    private int pos_marked;
63  
64    public ReaderInputStream(Reader reader)
65    {
66      this.reader = reader;
67      this.encoding = "UTF-8";
68    }
69  
70    void setEncoding(String encoding)
71    {
72      this.encoding = encoding;
73    }
74  
75    public int read()
76      throws IOException
77    {
78      if (extra != null)
79        {
80          int result = extra[pos];
81          pos++;
82          if (pos >= extra.length)
83            {
84              extra = null;
85            }
86          return result;
87        }
88      return reader.read();
89    }
90  
91    public int read(byte[] b)
92      throws IOException
93    {
94      return read(b, 0, b.length);
95    }
96  
97    public int read(byte[] b, int off, int len)
98      throws IOException
99    {
100     if (len == 0)
101       {
102         return 0;
103       }
104 
105     if (extra != null)
106       {
107         int available = extra.length - pos;
108         int l = available < len ? available : len;
109         System.arraycopy(extra, 0, b, off, l);
110         pos += l;
111         if (pos >= extra.length)
112           {
113             extra = null;
114           }
115         return l;
116       }
117 
118     char[] c = new char[len];
119     int l = reader.read(c, 0, len);
120     if (l == -1)
121       {
122         return -1;
123       }
124 
125     String s = new String(c, 0, l);
126     byte[] d = s.getBytes(encoding);
127     
128     int available = d.length;
129     int more = d.length - len;
130     if (more > 0)
131       {
132         extra = new byte[more];
133         pos = 0;
134         System.arraycopy(d, len, extra, 0, more);
135         available -= more;
136       }
137        
138     System.arraycopy(d, 0, b, off, available);
139     return available;
140   }
141 
142   public void close()
143     throws IOException
144   {
145     reader.close();
146   }
147 
148   public boolean markSupported()
149   {
150     return reader.markSupported();
151   }
152 
153   public void mark(int limit)
154   {
155     if (extra != null)
156       {
157         extra_marked = new byte[extra.length];
158         System.arraycopy(extra, 0, extra_marked, 0, extra.length);
159         pos_marked = pos;
160       }
161     else
162       {
163         extra_marked = null;
164       }
165 
166     try
167       {
168         // Note that this might be a bit more than asked for.
169         // Because we might also have the extra_marked bytes.
170         // That is fine (and necessary for reset() to work).
171         reader.mark(limit);
172       }
173     catch (IOException ioe)
174       {
175         throw new RuntimeException(ioe);
176       }
177   }
178 
179   public void reset()
180     throws IOException
181   {
182     extra = extra_marked;
183     pos = pos_marked;
184     extra_marked = null;
185 
186     reader.reset();
187   }
188 
189   public long skip(long n)
190     throws IOException
191   {
192     long done = 0;
193     if (extra != null)
194       {
195         int available = extra.length - pos;
196         done = available < n ? available : n;
197         pos += done;
198         if (pos >= extra.length)
199           {
200             extra = null;
201           }
202       }
203 
204     n -= done;
205     if (n > 0)
206       {
207         return reader.skip(n) + done;
208       }
209     else
210       {
211         return done;
212       }
213   }
214 
215   /**
216    *  Returns conservative number of bytes available without blocking.
217    *  Actual number of bytes that can be read without blocking might
218    *  be (much) bigger.
219    */
220   public int available()
221     throws IOException
222   {
223     if (extra != null)
224       {
225         return pos - extra.length;
226       }
227 
228     return reader.ready() ? 1 : 0;
229   }
230 
231   public String toString()
232   {
233     return getClass().getName() + "[" + reader + ", " + encoding + "]";
234   }
235   
236 }
237