View Javadoc

1   /*
2    * $Id: UnparseableFilterRandomAccessFile.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.File;
11  import java.io.FileNotFoundException;
12  import java.io.IOException;
13  import java.io.RandomAccessFile;
14  import java.util.ArrayList;
15  import java.util.Arrays;
16  import java.util.Collections;
17  import java.util.Comparator;
18  import java.util.Iterator;
19  import java.util.List;
20  
21  import org.eclipse.jface.text.IRegion;
22  
23  /***
24   * A wrapper for a java.io.RandomAccessFile that blanks out portions of the 
25   * file. Given a list of text regions to ignore, it
26   * performs exactly the same as an ordinary RandomAccessFile, except that
27   * all text in the specified regions is replaced with spaces.  This allows
28   * parsers to easily work around portions of the text that are known to be
29   * invalid.
30   */
31  public class UnparseableFilterRandomAccessFile extends RandomAccessFile
32  {
33     /***
34      * A list of {@link IRegion}s to blank out when reading from the file.
35      */
36     protected List _lInvalidRegions = new ArrayList();
37     /***
38      * Creates a new UnparseableFilterRandomAccessFile.
39      * @param file The file object
40      * @param mode The file mode.  
41      * @param regions Array of regions to blank out
42      * @throws FileNotFoundException if <code>file</code> cannot be opened for
43      *         random access.
44      * @see java.io.RandomAccessFile#mode
45      */
46     public UnparseableFilterRandomAccessFile(
47        File file,
48        String mode,
49        IRegion[] regions)
50        throws FileNotFoundException
51     {
52        super(file, mode);
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     }
73  
74     /***
75      * Checks the list of blank-out regions for one containing a specific
76      * offset .
77      * @param offset The offset to locate
78      * @return The blank-out region containing the offset, or <code>null</code>
79      *         if it does not fall in a blank-out region
80      */
81     protected IRegion findContainingRegion(long offset)
82     {
83        Iterator it = _lInvalidRegions.iterator();
84        while (it.hasNext())
85        {
86           IRegion r = (IRegion) it.next();
87           if (offset >= r.getOffset()
88              && offset < (r.getOffset() + r.getLength()))
89           {
90              return r;
91           }
92        }
93        return null;
94     }
95  
96     /* (non-Javadoc)
97      * @see java.io.RandomAccessFile#read()
98      */
99     public int read() throws IOException
100    {
101       long lOffset = this.getFilePointer();
102       int iReturn = super.read();
103       if (findContainingRegion(lOffset) != null)
104       {
105          iReturn = (int) ' ';
106       }
107       return iReturn;
108    }
109 
110    /* (non-Javadoc)
111     * @see java.io.RandomAccessFile#read(byte[],int,int)
112     */
113    public int read(byte[] b, int off, int len) throws IOException
114    {
115       long lOffset = this.getFilePointer();
116       int iNumRead = super.read(b, off, len);
117       IRegion r = null;
118       for (int i = 0; i < iNumRead; i++, lOffset++)
119       {
120          if (r == null || lOffset >= (r.getOffset() + r.getLength()))
121          {
122             r = findContainingRegion(lOffset);
123          }
124          if (r != null)
125          {
126             b[off + i] = ' ';
127          }
128       }
129       return iNumRead;
130    }
131 
132    /* (non-Javadoc)
133     * @see java.io.RandomAccessFile#read(byte[])
134     */
135    public int read(byte[] b) throws IOException
136    {
137       long lOffset = this.getFilePointer();
138       int iNumRead = super.read(b);
139       IRegion r = null;
140       for (int i = 0; i < iNumRead; i++, lOffset++)
141       {
142          if (r == null || lOffset >= (r.getOffset() + r.getLength()))
143          {
144             r = findContainingRegion(lOffset);
145          }
146          if (r != null)
147          {
148             b[i] = ' ';
149          }
150       }
151       return iNumRead;
152    }
153 
154    /***
155     * Reads a character from the file at the current seek position, ignoring
156     * the blank-out regions .
157     * @return The character read from the file
158     * @throws IOException if a read error occurs.
159     */
160    public int readUnfiltered() throws IOException
161    {
162       return super.read();
163    }
164 
165    /***
166     * Reads up to len bytes from this file into an array of bytes, ignoring
167     * the blank-out regions.
168     * @param b The buffer into which data is read
169     * @param off The start offset of the data
170     * @param len The maximum number of bytes to read
171     * @return The number of bytes read, or -1 if there is no more data because
172     *         EOF has been reached
173     * @throws IOException if a read error occurs.
174     */
175    public int readUnfiltered(byte[] b, int off, int len) throws IOException
176    {
177       return super.read(b, off, len);
178    }
179 
180    /***
181     * Reads up to b.length bytes from this file into an array of bytes, ignoring
182     * the blank-out regions.
183     * @param b The buffer into which data is read
184     * @return The number of bytes read, or -1 if there is no more data because
185     *         EOF has been reached
186     * @throws IOException if a read error occurs.
187     */
188    public int readUnfiltered(byte[] b) throws IOException
189    {
190       return super.read(b);
191    }
192 
193 }