KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > text > rtf > AbstractFilter


1 /*
2  * @(#)AbstractFilter.java 1.11 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing.text.rtf;
8
9 import java.io.*;
10 import java.lang.*;
11
12 /**
13  * A generic superclass for streams which read and parse text
14  * consisting of runs of characters interspersed with occasional
15  * ``specials'' (formatting characters).
16  *
17  * <p> Most of the functionality
18  * of this class would be redundant except that the
19  * <code>ByteToChar</code> converters
20  * are suddenly private API. Presumably this class will disappear
21  * when the API is made public again. (sigh) That will also let us handle
22  * multibyte character sets...
23  *
24  * <P> A subclass should override at least <code>write(char)</code>
25  * and <code>writeSpecial(int)</code>. For efficiency's sake it's a
26  * good idea to override <code>write(String)</code> as well. The subclass'
27  * initializer may also install appropriate translation and specials tables.
28  *
29  * @see OutputStream
30  */

31 abstract class AbstractFilter extends OutputStream
32 {
33     /** A table mapping bytes to characters */
34     protected char translationTable[];
35     /** A table indicating which byte values should be interpreted as
36      * characters and which should be treated as formatting codes */

37     protected boolean specialsTable[];
38
39     /** A translation table which does ISO Latin-1 (trivial) */
40     static final char latin1TranslationTable[];
41     /** A specials table which indicates that no characters are special */
42     static final boolean noSpecialsTable[];
43     /** A specials table which indicates that all characters are special */
44     static final boolean allSpecialsTable[];
45
46     static {
47       int i;
48
49       noSpecialsTable = new boolean[256];
50       for (i = 0; i < 256; i++)
51     noSpecialsTable[i] = false;
52
53       allSpecialsTable = new boolean[256];
54       for (i = 0; i < 256; i++)
55     allSpecialsTable[i] = true;
56
57       latin1TranslationTable = new char[256];
58       for (i = 0; i < 256; i++)
59     latin1TranslationTable[i] = (char)i;
60     }
61
62     /**
63      * A convenience method that reads text from a FileInputStream
64      * and writes it to the receiver.
65      * The format in which the file
66      * is read is determined by the concrete subclass of
67      * AbstractFilter to which this method is sent.
68      * <p>This method does not close the receiver after reaching EOF on
69      * the input stream.
70      * The user must call <code>close()</code> to ensure that all
71      * data are processed.
72      *
73      * @param in An InputStream providing text.
74      */

75     public void readFromStream(InputStream in)
76       throws IOException
77     {
78         byte buf[];
79         int count;
80         
81     buf = new byte[16384];
82     
83     while(true) {
84         count = in.read(buf);
85         if (count < 0)
86             break;
87         
88         this.write(buf, 0, count);
89     }
90     }
91
92     public void readFromReader(Reader in)
93       throws IOException
94     {
95         char buf[];
96         int count;
97         
98     buf = new char[2048];
99     
100     while(true) {
101         count = in.read(buf);
102         if (count < 0)
103             break;
104         for (int i = 0; i < count; i++) {
105           this.write(buf[i]);
106         }
107     }
108     }
109
110     public AbstractFilter()
111     {
112         translationTable = latin1TranslationTable;
113     specialsTable = noSpecialsTable;
114     }
115
116     /**
117      * Implements the abstract method of OutputStream, of which this class
118      * is a subclass.
119      */

120     public void write(int b)
121       throws IOException
122     {
123       if (b < 0)
124     b += 256;
125       if (specialsTable[b])
126     writeSpecial(b);
127       else {
128     char ch = translationTable[b];
129     if (ch != (char)0)
130       write(ch);
131       }
132     }
133
134     /**
135      * Implements the buffer-at-a-time write method for greater
136      * efficiency.
137      *
138      * <p> <strong>PENDING:</strong> Does <code>write(byte[])</code>
139      * call <code>write(byte[], int, int)</code> or is it the other way
140      * around?
141      */

142     public void write(byte[] buf, int off, int len)
143       throws IOException
144     {
145       StringBuffer JavaDoc accumulator = null;
146       while (len > 0) {
147         short b = (short)buf[off];
148
149     // stupid signed bytes
150
if (b < 0)
151             b += 256;
152
153     if (specialsTable[b]) {
154       if (accumulator != null) {
155         write(accumulator.toString());
156         accumulator = null;
157       }
158       writeSpecial(b);
159     } else {
160       char ch = translationTable[b];
161       if (ch != (char)0) {
162         if (accumulator == null)
163           accumulator = new StringBuffer JavaDoc();
164         accumulator.append(ch);
165       }
166     }
167     
168     len --;
169     off ++;
170       }
171
172       if (accumulator != null)
173     write(accumulator.toString());
174     }
175
176     /**
177      * Hopefully, all subclasses will override this method to accept strings
178      * of text, but if they don't, AbstractFilter's implementation
179      * will spoon-feed them via <code>write(char)</code>.
180      *
181      * @param s The string of non-special characters written to the
182      * OutputStream.
183      */

184     public void write(String JavaDoc s)
185       throws IOException
186     {
187       int index, length;
188
189       length = s.length();
190       for(index = 0; index < length; index ++) {
191     write(s.charAt(index));
192       }
193     }
194
195     /**
196      * Subclasses must provide an implementation of this method which
197      * accepts a single (non-special) character.
198      *
199      * @param ch The character written to the OutputStream.
200      */

201     protected abstract void write(char ch) throws IOException;
202
203     /**
204      * Subclasses must provide an implementation of this method which
205      * accepts a single special byte. No translation is performed
206      * on specials.
207      *
208      * @param b The byte written to the OutputStream.
209      */

210     protected abstract void writeSpecial(int b) throws IOException;
211 }
212
213
214
Popular Tags