SingleByteCharsetConverter.java
上传用户:sxlinghang
上传日期:2022-07-20
资源大小:1405k
文件大小:7k
源码类别:

数据库编程

开发平台:

Java

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