/** ******************************************************************************* * Copyright (C) 1996-2005, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* * ******************************************************************************* */ package com.ibm.icu4jni.charset; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.util.HashMap; import java.util.Map; // BEGIN android-removed // import com.ibm.icu4jni.common.ErrorCode; // import com.ibm.icu4jni.converters.NativeConverter; // END android-removed public final class CharsetICU extends Charset{ private String icuCanonicalName; /** * Constructor to create a the CharsetICU object * @param canonicalName the canonical name as a string * @param aliases the alias set as an array of strings * @stable ICU 2.4 */ protected CharsetICU(String canonicalName, String icuCanonName, String[] aliases) { super(canonicalName,aliases); icuCanonicalName = icuCanonName; } /** * Returns a new decoder instance of this charset object * @return a new decoder object * @stable ICU 2.4 */ public CharsetDecoder newDecoder(){ // the arrays are locals and not // instance variables since the // methods on this class need to // be thread safe long converterHandle = NativeConverter.openConverter(icuCanonicalName); return new CharsetDecoderICU(this,converterHandle); }; // hardCoded list of replacement bytes private static final Map subByteMap = new HashMap(); static{ subByteMap.put("UTF-32",new byte[]{0x00, 0x00, (byte)0xfe, (byte)0xff}); subByteMap.put("ibm-16684_P110-2003",new byte[]{0x40, 0x40}); // make \u3000 the sub char subByteMap.put("ibm-971_P100-1995",new byte[]{(byte)0xa1, (byte)0xa1}); // make \u3000 the sub char } /** * Returns a new encoder object of the charset * @return a new encoder * @stable ICU 2.4 */ public CharsetEncoder newEncoder(){ // the arrays are locals and not // instance variables since the // methods on this class need to // be thread safe long converterHandle = NativeConverter.openConverter(icuCanonicalName); //According to the contract all converters should have non-empty replacement byte[] replacement = NativeConverter.getSubstitutionBytes(converterHandle); try{ return new CharsetEncoderICU(this,converterHandle, replacement); }catch(IllegalArgumentException ex){ // work around for the non-sensical check in the nio API that // a substitution character must be mappable while decoding!! replacement = (byte[])subByteMap.get(icuCanonicalName); if(replacement==null){ replacement = new byte[NativeConverter.getMinBytesPerChar(converterHandle)]; for(int i=0; i<replacement.length; i++){ replacement[i]= 0x3f; } } NativeConverter.setSubstitutionBytes(converterHandle, replacement, replacement.length); return new CharsetEncoderICU(this,converterHandle, replacement); } } /** * Ascertains if a charset is a sub set of this charset * @param cs charset to test * @return true if the given charset is a subset of this charset * @stable ICU 2.4 * * //CSDL: major changes by Jack */ public boolean contains(Charset cs){ if (null == cs) { return false; } else if (this.equals(cs)) { return true; } long converterHandle1 = 0; long converterHandle2 = 0; try { converterHandle1 = NativeConverter.openConverter(this.name()); if (converterHandle1 > 0) { converterHandle2 = NativeConverter.openConverter(cs.name()); if (converterHandle2 > 0) { return NativeConverter.contains(converterHandle1, converterHandle2); } } return false; } finally { if (0 != converterHandle1) { NativeConverter.closeConverter(converterHandle1); if (0 != converterHandle2) { NativeConverter.closeConverter(converterHandle2); } } } } }