KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mysql > jdbc > SingleByteCharsetConverter


1 /*
2    Copyright (C) 2002 MySQL AB
3
4       This program is free software; you can redistribute it and/or modify
5       it under the terms of the GNU General Public License as published by
6       the Free Software Foundation; either version 2 of the License, or
7       (at your option) any later version.
8
9       This program is distributed in the hope that it will be useful,
10       but WITHOUT ANY WARRANTY; without even the implied warranty of
11       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12       GNU General Public License for more details.
13
14       You should have received a copy of the GNU General Public License
15       along with this program; if not, write to the Free Software
16       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18  */

19 package com.mysql.jdbc;
20
21 import java.io.UnsupportedEncodingException JavaDoc;
22
23 import java.util.HashMap JavaDoc;
24 import java.util.Map JavaDoc;
25
26
27 /**
28  * Converter for char[]->byte[] and byte[]->char[] for single-byte character
29  * sets. Much faster (5-6x) than the built-in solution that ships with the
30  * JVM, even with JDK-1.4.x and NewIo.
31  *
32  * @author Mark Matthews
33  */

34 public class SingleByteCharsetConverter {
35     // The initial charToByteMap, with all char mappings mapped
36
// to (byte) '?', so that unknown characters are mapped to '?'
37
// instead of '\0' (which means end-of-string to MySQL).
38
private static byte[] unknownCharsMap = new byte[65536];
39     private static final int BYTE_RANGE = (1 + Byte.MAX_VALUE) - Byte.MIN_VALUE;
40     private static final Map JavaDoc CONVERTER_MAP = new HashMap JavaDoc();
41     private static byte[] allBytes = new byte[BYTE_RANGE];
42
43     static {
44         for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
45             allBytes[i - Byte.MIN_VALUE] = (byte) i;
46         }
47
48         for (int i = 0; i < unknownCharsMap.length; i++) {
49             unknownCharsMap[i] = (byte) '?'; // use something 'sane' for unknown chars
50
}
51     }
52
53     private char[] byteToChars = new char[BYTE_RANGE];
54     private byte[] charToByteMap = new byte[65536];
55
56     /**
57      * Prevent instantiation, called out of static method initCharset().
58      *
59      * @param encodingName a JVM character encoding
60      *
61      * @throws UnsupportedEncodingException if the JVM does not support the
62      * encoding
63      */

64     private SingleByteCharsetConverter(String JavaDoc encodingName)
65         throws UnsupportedEncodingException JavaDoc {
66         String JavaDoc allBytesString = new String JavaDoc(allBytes, 0, BYTE_RANGE, encodingName);
67         int allBytesLen = allBytesString.length();
68
69         System.arraycopy(unknownCharsMap, 0, charToByteMap, 0,
70             charToByteMap.length);
71
72         for (int i = 0; (i < BYTE_RANGE) && (i < allBytesLen); i++) {
73             char c = allBytesString.charAt(i);
74             byteToChars[i] = c;
75             charToByteMap[c] = allBytes[i];
76         }
77     }
78
79     /**
80      * Get a converter for the given encoding name
81      *
82      * @param encodingName the Java character encoding name
83      *
84      * @return a converter for the given encoding name
85      *
86      * @throws UnsupportedEncodingException if the character encoding is not
87      * supported
88      */

89     public static synchronized SingleByteCharsetConverter getInstance(
90         String JavaDoc encodingName) throws UnsupportedEncodingException JavaDoc {
91         SingleByteCharsetConverter instance = (SingleByteCharsetConverter) CONVERTER_MAP
92             .get(encodingName);
93
94         if (instance == null) {
95             instance = initCharset(encodingName);
96         }
97
98         return instance;
99     }
100
101     /**
102      * Initialize the shared instance of a converter for the given character
103      * encoding.
104      *
105      * @param javaEncodingName the Java name for the character set to
106      * initialize
107      *
108      * @return a converter for the given character set
109      *
110      * @throws UnsupportedEncodingException if the character encoding is not
111      * supported
112      */

113     public static SingleByteCharsetConverter initCharset(
114         String JavaDoc javaEncodingName) throws UnsupportedEncodingException JavaDoc {
115         String JavaDoc mysqlEncodingName = (String JavaDoc) CharsetMapping.JAVA_TO_MYSQL_CHARSET_MAP
116             .get(javaEncodingName);
117
118         if (mysqlEncodingName == null) {
119             return null;
120         }
121
122         if (CharsetMapping.MULTIBYTE_CHARSETS.containsKey(mysqlEncodingName)) {
123             return null;
124         }
125
126         SingleByteCharsetConverter converter = new SingleByteCharsetConverter(javaEncodingName);
127
128         CONVERTER_MAP.put(javaEncodingName, converter);
129
130         return converter;
131     }
132
133     /**
134      * Convert the byte buffer from startPos to a length of length to a string
135      * using the default platform encoding.
136      *
137      * @param buffer the bytes to convert
138      * @param startPos the index to start at
139      * @param length the number of bytes to convert
140      *
141      * @return the String representation of the given bytes
142      */

143     public static String JavaDoc toStringDefaultEncoding(byte[] buffer, int startPos,
144         int length) {
145         return new String JavaDoc(buffer, startPos, length);
146     }
147
148     /**
149      * Convert the given string to an array of bytes.
150      *
151      * @param s the String to convert
152      *
153      * @return the bytes that make up the String
154      */

155     public final byte[] toBytes(String JavaDoc s) {
156         if (s == null) {
157             return null;
158         }
159
160         int length = s.length();
161         byte[] bytes = new byte[length];
162
163         for (int i = 0; i < length; i++) {
164             char c = s.charAt(i);
165             bytes[i] = charToByteMap[c];
166         }
167
168         return bytes;
169     }
170
171     private final static byte[] EMPTY_BYTE_ARRAY = new byte[0];
172     
173     /**
174      * Convert the given string to an array of bytes.
175      *
176      * @param s the String to convert
177      * @param offset the offset to start at
178      * @param length length (max) to convert
179      *
180      * @return the bytes that make up the String
181      */

182     public final byte[] toBytes(String JavaDoc s, int offset, int length) {
183         if (s == null) {
184             return null;
185         }
186
187         if (length == 0) {
188             return EMPTY_BYTE_ARRAY;
189         }
190         
191         int stringLength = s.length();
192         byte[] bytes = new byte[length];
193
194        
195         for (int i = 0; (i < length); i++) {
196             char c = s.charAt(i + offset);
197             bytes[i] = charToByteMap[c];
198         }
199
200         return bytes;
201     }
202
203     /**
204      * Convert the byte buffer to a string using this instance's character
205      * encoding.
206      *
207      * @param buffer the bytes to convert to a String
208      *
209      * @return the converted String
210      */

211     public final String JavaDoc toString(byte[] buffer) {
212         return toString(buffer, 0, buffer.length);
213     }
214
215     /**
216      * Convert the byte buffer from startPos to a length of length to a string
217      * using this instance's character encoding.
218      *
219      * @param buffer the bytes to convert
220      * @param startPos the index to start at
221      * @param length the number of bytes to convert
222      *
223      * @return the String representation of the given bytes
224      */

225     public final String JavaDoc toString(byte[] buffer, int startPos, int length) {
226         char[] charArray = new char[length];
227         int readpoint = startPos;
228
229         for (int i = 0; i < length; i++) {
230             charArray[i] = byteToChars[(int) buffer[readpoint] - Byte.MIN_VALUE];
231             readpoint++;
232         }
233
234         return new String JavaDoc(charArray);
235     }
236 }
237
Popular Tags