Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/mysql/jdbc/SingleByteCharsetConverter.java


1   /*
2    Copyright (C) 2002-2004 MySQL AB
3   
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of version 2 of the GNU General Public License as
6    published by the Free Software Foundation.
7    
8   
9    There are special exceptions to the terms and conditions of the GPL 
10   as it is applied to this software. View the full text of the 
11   exception exception in file EXCEPTIONS-CONNECTOR-J in the directory of this 
12   software distribution.
13  
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18  
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  
23   */
24  package com.mysql.jdbc;
25  
26  import java.io.UnsupportedEncodingException;
27  import java.util.HashMap;
28  import java.util.Map;
29  
30  
31  /**
32   * Converter for char[]->byte[] and byte[]->char[] for single-byte character
33   * sets. Much faster (5-6x) than the built-in solution that ships with the
34   * JVM, even with JDK-1.4.x and NewIo.
35   *
36   * @author Mark Matthews
37   */
38  public class SingleByteCharsetConverter {
39      // The initial charToByteMap, with all char mappings mapped 
40      // to (byte) '?', so that unknown characters are mapped to '?'
41      // instead of '\0' (which means end-of-string to MySQL).
42      private static byte[] unknownCharsMap = new byte[65536];
43      private static final int BYTE_RANGE = (1 + Byte.MAX_VALUE) - Byte.MIN_VALUE;
44      private static final Map CONVERTER_MAP = new HashMap();
45      private static byte[] allBytes = new byte[BYTE_RANGE];
46  
47      static {
48          for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
49              allBytes[i - Byte.MIN_VALUE] = (byte) i;
50          }
51  
52          for (int i = 0; i < unknownCharsMap.length; i++) {
53              unknownCharsMap[i] = (byte) '?'; // use something 'sane' for unknown chars
54          }
55      }
56  
57      private char[] byteToChars = new char[BYTE_RANGE];
58      private byte[] charToByteMap = new byte[65536];
59  
60      /**
61       * Prevent instantiation, called out of static method initCharset().
62       *
63       * @param encodingName a JVM character encoding
64       *
65       * @throws UnsupportedEncodingException if the JVM does not support the
66       *         encoding
67       */
68      private SingleByteCharsetConverter(String encodingName)
69          throws UnsupportedEncodingException {
70          String allBytesString = new String(allBytes, 0, BYTE_RANGE, encodingName);
71          int allBytesLen = allBytesString.length();
72  
73          System.arraycopy(unknownCharsMap, 0, charToByteMap, 0,
74              charToByteMap.length);
75  
76          for (int i = 0; (i < BYTE_RANGE) && (i < allBytesLen); i++) {
77              char c = allBytesString.charAt(i);
78              byteToChars[i] = c;
79              charToByteMap[c] = allBytes[i];
80          }
81      }
82  
83      /**
84       * Get a converter for the given encoding name
85       *
86       * @param encodingName the Java character encoding name
87       *
88       * @return a converter for the given encoding name
89       *
90       * @throws UnsupportedEncodingException if the character encoding is not
91       *         supported
92       */
93      public static synchronized SingleByteCharsetConverter getInstance(
94          String encodingName) throws UnsupportedEncodingException {
95          SingleByteCharsetConverter instance = (SingleByteCharsetConverter) CONVERTER_MAP
96              .get(encodingName);
97  
98          if (instance == null) {
99              instance = initCharset(encodingName);
100         }
101 
102         return instance;
103     }
104 
105     /**
106      * Initialize the shared instance of a converter for the given character
107      * encoding.
108      *
109      * @param javaEncodingName the Java name for the character set to
110      *        initialize
111      *
112      * @return a converter for the given character set
113      *
114      * @throws UnsupportedEncodingException if the character encoding is not
115      *         supported
116      */
117     public static SingleByteCharsetConverter initCharset(
118         String javaEncodingName) throws UnsupportedEncodingException {
119         String mysqlEncodingName = (String) CharsetMapping.JAVA_TO_MYSQL_CHARSET_MAP
120             .get(javaEncodingName);
121 
122         if (mysqlEncodingName == null) {
123             return null;
124         }
125 
126         if (CharsetMapping.MULTIBYTE_CHARSETS.containsKey(mysqlEncodingName)) {
127             return null;
128         }
129 
130         SingleByteCharsetConverter converter = new SingleByteCharsetConverter(javaEncodingName);
131 
132         CONVERTER_MAP.put(javaEncodingName, converter);
133 
134         return converter;
135     }
136 
137     /**
138      * Convert the byte buffer from startPos to a length of length to a string
139      * using the default platform encoding.
140      *
141      * @param buffer the bytes to convert
142      * @param startPos the index to start at
143      * @param length the number of bytes to convert
144      *
145      * @return the String representation of the given bytes
146      */
147     public static String toStringDefaultEncoding(byte[] buffer, int startPos,
148         int length) {
149         return new String(buffer, startPos, length);
150     }
151 
152     /**
153      * Convert the given string to an array of bytes.
154      *
155      * @param s the String to convert
156      *
157      * @return the bytes that make up the String
158      */
159     public final byte[] toBytes(String s) {
160         if (s == null) {
161             return null;
162         }
163 
164         int length = s.length();
165         byte[] bytes = new byte[length];
166 
167         for (int i = 0; i < length; i++) {
168             char c = s.charAt(i);
169             bytes[i] = charToByteMap[c];
170         }
171 
172         return bytes;
173     }
174 
175     private final static byte[] EMPTY_BYTE_ARRAY = new byte[0];
176     
177     /**
178      * Convert the given string to an array of bytes.
179      *
180      * @param s the String to convert
181      * @param offset the offset to start at
182      * @param length length (max) to convert
183      *
184      * @return the bytes that make up the String
185      */
186     public final byte[] toBytes(String s, int offset, int length) {
187         if (s == null) {
188             return null;
189         }
190 
191         if (length == 0) {
192           return EMPTY_BYTE_ARRAY;
193         }
194         
195         int stringLength = s.length();
196         byte[] bytes = new byte[length];
197 
198        
199         for (int i = 0; (i < length); i++) {
200             char c = s.charAt(i + offset);
201             bytes[i] = charToByteMap[c];
202         }
203 
204         return bytes;
205     }
206 
207     /**
208      * Convert the byte buffer to a string using this instance's character
209      * encoding.
210      *
211      * @param buffer the bytes to convert to a String
212      *
213      * @return the converted String
214      */
215     public final String toString(byte[] buffer) {
216         return toString(buffer, 0, buffer.length);
217     }
218 
219     /**
220      * Convert the byte buffer from startPos to a length of length to a string
221      * using this instance's character encoding.
222      *
223      * @param buffer the bytes to convert
224      * @param startPos the index to start at
225      * @param length the number of bytes to convert
226      *
227      * @return the String representation of the given bytes
228      */
229     public final String toString(byte[] buffer, int startPos, int length) {
230         char[] charArray = new char[length];
231         int readpoint = startPos;
232 
233         for (int i = 0; i < length; i++) {
234             charArray[i] = byteToChars[(int) buffer[readpoint] - Byte.MIN_VALUE];
235             readpoint++;
236         }
237 
238         return new String(charArray);
239     }
240 }