17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package javax.swing.text.rtf;
26
27 import java.io.*;
28 import java.lang.*;
29
30 /**
31 * A generic superclass for streams which read and parse text
32 * consisting of runs of characters interspersed with occasional
33 * ``specials'' (formatting characters).
34 *
35 * <p> Most of the functionality
36 * of this class would be redundant except that the
37 * <code>ByteToChar</code> converters
38 * are suddenly private API. Presumably this class will disappear
39 * when the API is made public again. (sigh) That will also let us handle
40 * multibyte character sets...
41 *
42 * <P> A subclass should override at least <code>write(char)</code>
43 * and <code>writeSpecial(int)</code>. For efficiency's sake it's a
44 * good idea to override <code>write(String)</code> as well. The subclass'
45 * initializer may also install appropriate translation and specials tables.
46 *
47 * @see OutputStream
48 */
49 abstract class AbstractFilter extends OutputStream
50 {
51 /** A table mapping bytes to characters */
52 protected char translationTable[];
53 /** A table indicating which byte values should be interpreted as
54 * characters and which should be treated as formatting codes */
55 protected boolean specialsTable[];
56
57 /** A translation table which does ISO Latin-1 (trivial) */
58 static final char latin1TranslationTable[];
59 /** A specials table which indicates that no characters are special */
60 static final boolean noSpecialsTable[];
61 /** A specials table which indicates that all characters are special */
62 static final boolean allSpecialsTable[];
63
64 static {
68 for (i = 0; i < 256; i++)
69 noSpecialsTable[i] = false;
70
71 allSpecialsTable = new boolean[256];
72 for (i = 0; i < 256; i++)
73 allSpecialsTable[i] = true;
74
75 latin1TranslationTable = new char[256];
76 for (i = 0; i < 256; i++)
77 latin1TranslationTable[i] = (char)i;
78 }
79
80 /**
81 * A convenience method that reads text from a FileInputStream
82 * and writes it to the receiver.
83 * The format in which the file
84 * is read is determined by the concrete subclass of
85 * AbstractFilter to which this method is sent.
86 * <p>This method does not close the receiver after reaching EOF on
87 * the input stream.
88 * The user must call <code>close()</code> to ensure that all
89 * data are processed.
90 *
91 * @param in An InputStream providing text.
92 */
93 public void readFromStream(InputStream in)
94 throws IOException
95 {
96 byte buf[];
97 int count;
98
99 buf = new byte[16384];
100
101 while(true) {
102 count = in.read(buf);
103 if (count < 0)
104 break;
105
106 this.write(buf, 0, count);
107 }
108 }
136 * is a subclass.
137 */
138 public void write(int b)
139 throws IOException
140 {
141 if (b < 0)
142 b += 256;
143 if (specialsTable[b])
144 writeSpecial(b);
145 else {
146 char ch = translationTable[b];
147 if (ch != (char)0)
148 write(ch);
149 }
150 }
151
152 /**
153 * Implements the buffer-at-a-time write method for greater
154 * efficiency.
155 *
156 * <p> <strong>PENDING:</strong> Does <code>write(byte[])</code>
157 * call <code>write(byte[], int, int)</code> or is it the other way
158 * around?
159 */
160 public void write(byte[] buf, int off, int len)
161 throws IOException
162 {
163 StringBuilder accumulator = null;
164 while (len > 0) {
165 short b = (short)buf[off];
166
167 // stupid signed bytes
168 if (b < 0)
169 b += 256;
170
171 if (specialsTable[b]) {
172 if (accumulator != null) {
173 write(accumulator.toString());
174 accumulator = null;
175 }
176 writeSpecial(b);
177 } else {
178 char ch = translationTable[b];
179 if (ch != (char)0) {
180 if (accumulator == null)
181 accumulator = new StringBuilder();
182 accumulator.append(ch);
183 }
184 }
185
186 len --;
187 off ++;
188 }
189
190 if (accumulator != null)
191 write(accumulator.toString());
192 }
193
194 /**
195 * Hopefully, all subclasses will override this method to accept strings
196 * of text, but if they don't, AbstractFilter's implementation
197 * will spoon-feed them via <code>write(char)</code>.
198 *
199 * @param s The string of non-special characters written to the
200 * OutputStream.
201 */
202 public void write(String s)
203 throws IOException
204 {
205 int index, length;
206
207 length = s.length();
208 for(index = 0; index < length; index ++) {
209 write(s.charAt(index));
210 }
211 }
212
213 /**
214 * Subclasses must provide an implementation of this method which
215 * accepts a single (non-special) character.
216 *
217 * @param ch The character written to the OutputStream.
|
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package javax.swing.text.rtf;
26
27 import java.io.*;
28 import java.lang.*;
29
30 /**
31 * A generic superclass for streams which read and parse text
32 * consisting of runs of characters interspersed with occasional
33 * ``specials'' (formatting characters).
34 *
35 * <p> Most of the functionality
36 * of this class would be redundant except that the
37 * {@code ByteToChar} converters
38 * are suddenly private API. Presumably this class will disappear
39 * when the API is made public again. (sigh) That will also let us handle
40 * multibyte character sets...
41 *
42 * <P> A subclass should override at least {@code write(char)}
43 * and {@code writeSpecial(int)}. For efficiency's sake it's a
44 * good idea to override {@code write(String)} as well. The subclass'
45 * initializer may also install appropriate translation and specials tables.
46 *
47 * @see OutputStream
48 */
49 abstract class AbstractFilter extends OutputStream
50 {
51 /** A table mapping bytes to characters */
52 protected char translationTable[];
53 /** A table indicating which byte values should be interpreted as
54 * characters and which should be treated as formatting codes */
55 protected boolean specialsTable[];
56
57 /** A translation table which does ISO Latin-1 (trivial) */
58 static final char latin1TranslationTable[];
59 /** A specials table which indicates that no characters are special */
60 static final boolean noSpecialsTable[];
61 /** A specials table which indicates that all characters are special */
62 static final boolean allSpecialsTable[];
63
64 static {
68 for (i = 0; i < 256; i++)
69 noSpecialsTable[i] = false;
70
71 allSpecialsTable = new boolean[256];
72 for (i = 0; i < 256; i++)
73 allSpecialsTable[i] = true;
74
75 latin1TranslationTable = new char[256];
76 for (i = 0; i < 256; i++)
77 latin1TranslationTable[i] = (char)i;
78 }
79
80 /**
81 * A convenience method that reads text from a FileInputStream
82 * and writes it to the receiver.
83 * The format in which the file
84 * is read is determined by the concrete subclass of
85 * AbstractFilter to which this method is sent.
86 * <p>This method does not close the receiver after reaching EOF on
87 * the input stream.
88 * The user must call {@code close()} to ensure that all
89 * data are processed.
90 *
91 * @param in An InputStream providing text.
92 */
93 public void readFromStream(InputStream in)
94 throws IOException
95 {
96 byte buf[];
97 int count;
98
99 buf = new byte[16384];
100
101 while(true) {
102 count = in.read(buf);
103 if (count < 0)
104 break;
105
106 this.write(buf, 0, count);
107 }
108 }
136 * is a subclass.
137 */
138 public void write(int b)
139 throws IOException
140 {
141 if (b < 0)
142 b += 256;
143 if (specialsTable[b])
144 writeSpecial(b);
145 else {
146 char ch = translationTable[b];
147 if (ch != (char)0)
148 write(ch);
149 }
150 }
151
152 /**
153 * Implements the buffer-at-a-time write method for greater
154 * efficiency.
155 *
156 * <p> <strong>PENDING:</strong> Does {@code write(byte[])}
157 * call {@code write(byte[], int, int)} or is it the other way
158 * around?
159 */
160 public void write(byte[] buf, int off, int len)
161 throws IOException
162 {
163 StringBuilder accumulator = null;
164 while (len > 0) {
165 short b = (short)buf[off];
166
167 // stupid signed bytes
168 if (b < 0)
169 b += 256;
170
171 if (specialsTable[b]) {
172 if (accumulator != null) {
173 write(accumulator.toString());
174 accumulator = null;
175 }
176 writeSpecial(b);
177 } else {
178 char ch = translationTable[b];
179 if (ch != (char)0) {
180 if (accumulator == null)
181 accumulator = new StringBuilder();
182 accumulator.append(ch);
183 }
184 }
185
186 len --;
187 off ++;
188 }
189
190 if (accumulator != null)
191 write(accumulator.toString());
192 }
193
194 /**
195 * Hopefully, all subclasses will override this method to accept strings
196 * of text, but if they don't, AbstractFilter's implementation
197 * will spoon-feed them via {@code write(char)}.
198 *
199 * @param s The string of non-special characters written to the
200 * OutputStream.
201 */
202 public void write(String s)
203 throws IOException
204 {
205 int index, length;
206
207 length = s.length();
208 for(index = 0; index < length; index ++) {
209 write(s.charAt(index));
210 }
211 }
212
213 /**
214 * Subclasses must provide an implementation of this method which
215 * accepts a single (non-special) character.
216 *
217 * @param ch The character written to the OutputStream.
|