1/** 2******************************************************************************* 3* Copyright (C) 1996-2005, International Business Machines Corporation and * 4* others. All Rights Reserved. * 5******************************************************************************* 6* 7******************************************************************************* 8*/ 9 10package com.ibm.icu4jni.charset; 11 12import java.nio.charset.Charset; 13import java.nio.charset.CharsetDecoder; 14import java.nio.charset.CharsetEncoder; 15import java.util.HashMap; 16import java.util.Map; 17 18// BEGIN android-removed 19// import com.ibm.icu4jni.common.ErrorCode; 20// import com.ibm.icu4jni.converters.NativeConverter; 21// END android-removed 22 23 24public final class CharsetICU extends Charset{ 25 private String icuCanonicalName; 26 /** 27 * Constructor to create a the CharsetICU object 28 * @param canonicalName the canonical name as a string 29 * @param aliases the alias set as an array of strings 30 * @stable ICU 2.4 31 */ 32 protected CharsetICU(String canonicalName, String icuCanonName, String[] aliases) { 33 super(canonicalName,aliases); 34 icuCanonicalName = icuCanonName; 35 36 } 37 /** 38 * Returns a new decoder instance of this charset object 39 * @return a new decoder object 40 * @stable ICU 2.4 41 */ 42 public CharsetDecoder newDecoder(){ 43 // the arrays are locals and not 44 // instance variables since the 45 // methods on this class need to 46 // be thread safe 47 long converterHandle = NativeConverter.openConverter(icuCanonicalName); 48 return new CharsetDecoderICU(this,converterHandle); 49 }; 50 51 // hardCoded list of replacement bytes 52 private static final Map subByteMap = new HashMap(); 53 static{ 54 subByteMap.put("UTF-32",new byte[]{0x00, 0x00, (byte)0xfe, (byte)0xff}); 55 subByteMap.put("ibm-16684_P110-2003",new byte[]{0x40, 0x40}); // make \u3000 the sub char 56 subByteMap.put("ibm-971_P100-1995",new byte[]{(byte)0xa1, (byte)0xa1}); // make \u3000 the sub char 57 } 58 /** 59 * Returns a new encoder object of the charset 60 * @return a new encoder 61 * @stable ICU 2.4 62 */ 63 public CharsetEncoder newEncoder(){ 64 // the arrays are locals and not 65 // instance variables since the 66 // methods on this class need to 67 // be thread safe 68 long converterHandle = NativeConverter.openConverter(icuCanonicalName); 69 70 //According to the contract all converters should have non-empty replacement 71 byte[] replacement = NativeConverter.getSubstitutionBytes(converterHandle); 72 73 try{ 74 return new CharsetEncoderICU(this,converterHandle, replacement); 75 }catch(IllegalArgumentException ex){ 76 // work around for the non-sensical check in the nio API that 77 // a substitution character must be mappable while decoding!! 78 replacement = (byte[])subByteMap.get(icuCanonicalName); 79 if(replacement==null){ 80 replacement = new byte[NativeConverter.getMinBytesPerChar(converterHandle)]; 81 for(int i=0; i<replacement.length; i++){ 82 replacement[i]= 0x3f; 83 } 84 } 85 NativeConverter.setSubstitutionBytes(converterHandle, replacement, replacement.length); 86 return new CharsetEncoderICU(this,converterHandle, replacement); 87 } 88 } 89 90 /** 91 * Ascertains if a charset is a sub set of this charset 92 * @param cs charset to test 93 * @return true if the given charset is a subset of this charset 94 * @stable ICU 2.4 95 * 96 * //CSDL: major changes by Jack 97 */ 98 public boolean contains(Charset cs){ 99 if (null == cs) { 100 return false; 101 } else if (this.equals(cs)) { 102 return true; 103 } 104 105 long converterHandle1 = 0; 106 long converterHandle2 = 0; 107 108 try { 109 converterHandle1 = NativeConverter.openConverter(this.name()); 110 if (converterHandle1 > 0) { 111 converterHandle2 = NativeConverter.openConverter(cs.name()); 112 if (converterHandle2 > 0) { 113 return NativeConverter.contains(converterHandle1, 114 converterHandle2); 115 } 116 } 117 return false; 118 } finally { 119 if (0 != converterHandle1) { 120 NativeConverter.closeConverter(converterHandle1); 121 if (0 != converterHandle2) { 122 NativeConverter.closeConverter(converterHandle2); 123 } 124 } 125 } 126 } 127} 128 129 130