KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > nu > xom > GenericWriter


1 /* Copyright 2002-2004 Elliotte Rusty Harold
2    
3    This library is free software; you can redistribute it and/or modify
4    it under the terms of version 2.1 of the GNU Lesser General Public
5    License as published by the Free Software Foundation.
6    
7    This library is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10    GNU Lesser General Public License for more details.
11    
12    You should have received a copy of the GNU Lesser General Public
13    License along with this library; if not, write to the
14    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15    Boston, MA 02111-1307 USA
16    
17    You can contact Elliotte Rusty Harold by sending e-mail to
18    elharo@metalab.unc.edu. Please include the word "XOM" in the
19    subject line. The XOM home page is located at http://www.xom.nu/
20 */

21
22 package nu.xom;
23
24 import java.io.ByteArrayOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.OutputStreamWriter JavaDoc;
27 import java.io.UnsupportedEncodingException JavaDoc;
28 import java.io.Writer JavaDoc;
29 import java.util.Locale JavaDoc;
30
31 /**
32  * <p>
33  * <code>GenericWriter</code> is a hack that figures out whether a
34  * character is or is not available in a particular encoding by writing
35  * it onto an OutputStream and seeing whether or not the character
36  * written is a question mark (Java's substitution character).
37  * There's a more staright-forward way to do this using
38  * <code>java.nio.Charset</code> in Java 1.4, but I'm not willing to
39  * assume Java 1.4.
40  * </p>
41  *
42  * @author Elliotte Rusty Harold
43  * @version 1.0
44  *
45  */

46 class GenericWriter extends TextWriter {
47     
48     
49     private ByteArrayOutputStream JavaDoc bout;
50     private OutputStreamWriter JavaDoc wout;
51     private boolean isJapanese = false;
52
53     
54     GenericWriter(Writer JavaDoc out, String JavaDoc encoding)
55       throws UnsupportedEncodingException JavaDoc {
56         
57         super(out, encoding);
58         bout = new ByteArrayOutputStream JavaDoc(32);
59         wout = new OutputStreamWriter JavaDoc(bout, encoding);
60         encoding = encoding.toUpperCase(Locale.ENGLISH);
61         if (encoding.indexOf("EUC-JP") > -1
62           || encoding.startsWith("EUC_JP")
63           || encoding.equals("SHIFT_JIS")
64           || encoding.equals("SJIS")
65           || encoding.equals("ISO-2022-JP")) {
66             isJapanese = true;
67         }
68         
69     }
70
71     
72     boolean needsEscaping(char c) {
73        
74         // assume everything has at least the ASCII characters
75
if (c <= 127) return false;
76         // work around various bugs in Japanese encodings
77
if (isJapanese) {
78             if (c == 0xA5) return true; // Yen symbol
79
if (c == 0x203E) return true; // Sun bugs in EUC-JP and SJIS
80
}
81         
82         boolean result = false;
83         try {
84             wout.write(c);
85             wout.flush();
86             byte[] data = bout.toByteArray();
87             if (data.length == 0) result = true; // surrogate pair
88
else if (data[0] == '?') result = true;
89             // work around various bugs in Japanese encodings
90
// especially in JDK 1.4.2_05
91
else if (isJapanese && data[0] == 0x21) result = true;
92         }
93         catch (IOException JavaDoc ex) {
94             // There really shouldn't be any IOException here.
95
// However character conversion bugs in Java 1.2
96
// sometimes throw one. In this case, we just say
97
// escape it.
98
return true;
99         }
100         catch (Error JavaDoc err) {
101             // This appears to be a wrapper around an undocumented
102
// sun.io.UnknownCharacterException or some such. In any
103
// case Java doesn't know how to output this character.
104
return true;
105         }
106         finally {
107             bout.reset();
108         }
109         return result;
110         
111     }
112    
113     
114 }
115
Popular Tags