View Javadoc

1   /*
2    * $Id: UnparseableFilterStream.java,v 1.7 2005/05/31 23:28:07 jlerner Exp $
3    *
4    * Copyright (c) 1999-2004, BBN Technologies, LLC.
5    * All rights reserved.
6    * http://www.daml.org/legal/opensource/bbn_license.html
7    */
8   package com.bbn.swede.core.dom;
9   
10  import java.io.IOException;
11  import java.io.InputStream;
12  import java.util.ArrayList;
13  import java.util.Arrays;
14  import java.util.Collections;
15  import java.util.Comparator;
16  import java.util.Iterator;
17  import java.util.List;
18  
19  import org.eclipse.jface.text.IRegion;
20  
21  /***
22   * A wrapper for a java.io.InputStream that blanks out portions of the stream. 
23   * It behaves like a regular stream with the exception that, given a list of 
24   * text regions to ignore, all text in the specified regions is replaced with 
25   * spaces.  This allows stream-based parsers to easily work around portions of 
26   * the text that are known to be invalid.
27   */
28  public class UnparseableFilterStream extends InputStream
29  {
30     /***
31      * The inner input stream.
32      */
33     protected InputStream _stream;
34     /***
35      * A list of {@link IRegion}s to blank out when reading from 
36      * <code>_stream</code>.
37      */
38     protected List _lInvalidRegions = new ArrayList();
39     /***
40      * The current position within the stream.
41      */
42     protected long _lPos;
43     
44     /***
45      * Creates a new UnparseableFilterStream based on a specified stream and
46      * set of blank-out regions.
47      * @param stream The stream to wrap
48      * @param regions The regions to blank out in the wrapped stream
49      */
50     public UnparseableFilterStream(InputStream stream, IRegion[] regions)
51     {
52        _stream = stream;
53        _lInvalidRegions.addAll(Arrays.asList(regions));
54        Collections.sort(_lInvalidRegions, new Comparator()
55        {
56  
57           public int compare(Object arg0, Object arg1)
58           {
59              IRegion r1 = (IRegion) arg0;
60              IRegion r2 = (IRegion) arg1;
61              if (r1.getOffset() < r2.getOffset())
62              {
63                 return -1;
64              }
65              if (r1.getOffset() > r2.getOffset())
66              {
67                 return 1;
68              }
69              return 0;
70           }
71        });
72        _lPos = 0;
73     }
74  
75     /***
76      * Checks the list of blank-out regions for one containing a specific
77      * offset .
78      * @param offset The offset to locate
79      * @return The blank-out region containing the offset, or <code>null</code>
80      *         if it does not fall in a blank-out region
81      */
82     protected IRegion findContainingRegion(long offset)
83     {
84        Iterator it = _lInvalidRegions.iterator();
85        while (it.hasNext())
86        {
87           IRegion r = (IRegion) it.next();
88           if (offset >= r.getOffset()
89              && offset < (r.getOffset() + r.getLength()))
90           {
91              return r;
92           }
93        }
94        return null;
95     }
96  
97     /* (non-Javadoc)
98      * @see java.io.InputStream#read()
99      */
100    public int read() throws IOException
101    {
102       int iReturn = _stream.read();
103       if (findContainingRegion(_lPos) != null)
104       {
105          iReturn = (int) ' ';
106       }
107       _lPos++;
108       return iReturn;
109    }
110 
111    /* (non-Javadoc)
112     * @see java.io.InputStream#read(byte[],int,int)
113     */
114    public int read(byte[] b, int off, int len) throws IOException
115    {
116       int iNumRead = _stream.read(b, off, len);
117       IRegion r = null;
118       for (int i = 0; i < iNumRead; i++, _lPos++)
119       {
120          if (r == null || _lPos >= (r.getOffset() + r.getLength()))
121          {
122             r = findContainingRegion(_lPos);
123          }
124          if (r != null)
125          {
126             b[off + i] = ' ';
127          }
128       }
129       return iNumRead;
130    }
131 
132    /* (non-Javadoc)
133     * @see java.io.InputStream#read(byte[])
134     */
135    public int read(byte[] b) throws IOException
136    {
137       int iNumRead = _stream.read(b);
138       IRegion r = null;
139       for (int i = 0; i < iNumRead; i++, _lPos++)
140       {
141          if (r == null || _lPos >= (r.getOffset() + r.getLength()))
142          {
143             r = findContainingRegion(_lPos);
144          }
145          if (r != null)
146          {
147             b[i] = ' ';
148          }
149       }
150       return iNumRead;
151    }
152 
153    /* (non-Javadoc)
154     * @see java.io.InputStream#available()
155     */
156    public int available() throws IOException
157    {
158       return _stream.available();
159    }
160 
161    /* (non-Javadoc)
162     * @see java.io.InputStream#close()
163     */
164    public void close() throws IOException
165    {
166       _stream.close();
167    }
168 
169    /* (non-Javadoc)
170     * @see java.io.InputStream#mark()
171     */
172    public synchronized void mark(int arg0)
173    {
174       _stream.mark(arg0);
175    }
176 
177    /* (non-Javadoc)
178     * @see java.io.InputStream#markSupported()
179     */
180    public boolean markSupported()
181    {
182       return _stream.markSupported();
183    }
184 
185    /* (non-Javadoc)
186     * @see java.io.InputStream#reset()
187     */
188    public synchronized void reset() throws IOException
189    {
190       _lPos = 0;
191       _stream.reset();
192    }
193 
194    /* (non-Javadoc)
195     * @see java.io.InputStream#skip()
196     */
197    public long skip(long arg0) throws IOException
198    {
199       _lPos += arg0;
200       return _stream.skip(arg0);
201    }
202 }