/* * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * Licensed Materials - Property of IBM * RMI-IIOP v1.0 * Copyright IBM Corp. 1998 1999 All Rights Reserved * */ package com.sun.corba.se.impl.encoding; import java.util.StringTokenizer; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.NoSuchElementException; import org.omg.CORBA.INITIALIZE; import org.omg.CORBA.CompletionStatus; import com.sun.corba.se.spi.logging.CORBALogDomains; import com.sun.corba.se.impl.logging.ORBUtilSystemException; public final class CodeSetComponentInfo { /** * CodeSetComponent is part of an IOR multi-component profile. Two * instances constitute a CodeSetComponentInfo (one for char and one * for wchar data) */ public static final class CodeSetComponent { int nativeCodeSet; int[] conversionCodeSets; public boolean equals( Object obj ) { if (this == obj) return true ; if (!(obj instanceof CodeSetComponent)) return false ; CodeSetComponent other = (CodeSetComponent)obj ; return (nativeCodeSet == other.nativeCodeSet) && Arrays.equals( conversionCodeSets, other.conversionCodeSets ) ; } public int hashCode() { int result = nativeCodeSet ; for (int ctr=0; ctr<conversionCodeSets.length; ctr++) result = 37*result + conversionCodeSets[ctr] ; return result ; } public CodeSetComponent() {} public CodeSetComponent(int nativeCodeSet, int[] conversionCodeSets) { this.nativeCodeSet = nativeCodeSet; if (conversionCodeSets == null) this.conversionCodeSets = new int[0]; else this.conversionCodeSets = conversionCodeSets; } public void read(MarshalInputStream in) { nativeCodeSet = in.read_ulong(); int len = in.read_long(); conversionCodeSets = new int[len]; in.read_ulong_array(conversionCodeSets, 0, len); } public void write(MarshalOutputStream out) { out.write_ulong(nativeCodeSet); out.write_long(conversionCodeSets.length); out.write_ulong_array(conversionCodeSets, 0, conversionCodeSets.length); } public String toString() { StringBuffer sbuf = new StringBuffer("CodeSetComponent("); sbuf.append("native:"); sbuf.append(Integer.toHexString(nativeCodeSet)); sbuf.append(" conversion:"); if (conversionCodeSets == null) sbuf.append("null"); else { for (int i = 0; i < conversionCodeSets.length; i++) { sbuf.append(Integer.toHexString(conversionCodeSets[i])); sbuf.append(' '); } } sbuf.append( ")" ) ; return sbuf.toString(); } } private CodeSetComponent forCharData; private CodeSetComponent forWCharData; public boolean equals( Object obj ) { if (this == obj) return true ; if (!(obj instanceof CodeSetComponentInfo)) return false ; CodeSetComponentInfo other = (CodeSetComponentInfo)obj ; return forCharData.equals( other.forCharData ) && forWCharData.equals( other.forWCharData ) ; } public int hashCode() { return forCharData.hashCode() ^ forWCharData.hashCode() ; } public String toString() { StringBuffer sbuf = new StringBuffer("CodeSetComponentInfo("); sbuf.append("char_data:"); sbuf.append(forCharData.toString()); sbuf.append(" wchar_data:"); sbuf.append(forWCharData.toString()); sbuf.append(")"); return sbuf.toString(); } public CodeSetComponentInfo() { forCharData = CodeSetComponentInfo.JAVASOFT_DEFAULT_CODESETS.forCharData; forWCharData = CodeSetComponentInfo.JAVASOFT_DEFAULT_CODESETS.forWCharData; } public CodeSetComponentInfo(CodeSetComponent charData, CodeSetComponent wcharData) { forCharData = charData; forWCharData = wcharData; } public void read(MarshalInputStream in) { forCharData = new CodeSetComponent(); forCharData.read(in); forWCharData = new CodeSetComponent(); forWCharData.read(in); } public void write(MarshalOutputStream out) { forCharData.write(out); forWCharData.write(out); } public CodeSetComponent getCharComponent() { return forCharData; } public CodeSetComponent getWCharComponent() { return forWCharData; } /** * CodeSetContext goes in a GIOP service context */ public static final class CodeSetContext { private int char_data; private int wchar_data; public CodeSetContext() {} public CodeSetContext(int charEncoding, int wcharEncoding) { char_data = charEncoding; wchar_data = wcharEncoding; } public void read(MarshalInputStream in) { char_data = in.read_ulong(); wchar_data = in.read_ulong(); } public void write(MarshalOutputStream out) { out.write_ulong(char_data); out.write_ulong(wchar_data); } public int getCharCodeSet() { return char_data; } public int getWCharCodeSet() { return wchar_data; } public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("CodeSetContext char set: "); sbuf.append(Integer.toHexString(char_data)); sbuf.append(" wchar set: "); sbuf.append(Integer.toHexString(wchar_data)); return sbuf.toString(); } } /** * Our default code set scheme is as follows: * * char data: * * Native code set: ISO 8859-1 (8-bit) * Conversion sets: UTF-8, ISO 646 (7-bit) * * wchar data: * * Native code set: UTF-16 * Conversion sets: UCS-2 * * Pre-Merlin/J2EE 1.3 JavaSoft ORBs listed ISO646 for char and * UCS-2 for wchar, and provided no conversion sets. They also * didn't do correct negotiation or provide the fallback sets. * UCS-2 is still in the conversion list for backwards compatibility. * * The fallbacks are UTF-8 for char and UTF-16 for wchar. * * In GIOP 1.1, interoperability with wchar is limited to 2 byte fixed * width encodings since its wchars aren't preceded by a length. * Thus, I've chosen not to include UTF-8 in the conversion set * for wchar data. * */ public static final CodeSetComponentInfo JAVASOFT_DEFAULT_CODESETS; static { CodeSetComponent charData = new CodeSetComponent(OSFCodeSetRegistry.ISO_8859_1.getNumber(), new int[] { OSFCodeSetRegistry.UTF_8.getNumber(), OSFCodeSetRegistry.ISO_646.getNumber() }); CodeSetComponent wcharData = new CodeSetComponent(OSFCodeSetRegistry.UTF_16.getNumber(), new int[] { OSFCodeSetRegistry.UCS_2.getNumber() }); JAVASOFT_DEFAULT_CODESETS = new CodeSetComponentInfo(charData, wcharData); } /** * Creates a CodeSetComponent from a String which contains a comma * delimited list of OSF Code Set Registry numbers. An INITIALIZE * exception is thrown if any of the numbers are not known by our * registry. Used by corba.ORB init. * * The first number in the list is taken as the native code set, * and the rest is the conversion code set list. * * The numbers can either be decimal or hex. */ public static CodeSetComponent createFromString(String str) { ORBUtilSystemException wrapper = ORBUtilSystemException.get( CORBALogDomains.RPC_ENCODING ) ; if (str == null || str.length() == 0) throw wrapper.badCodeSetString() ; StringTokenizer stok = new StringTokenizer(str, ", ", false); int nativeSet = 0; int conversionInts[] = null; try { // The first value is the native code set nativeSet = Integer.decode(stok.nextToken()).intValue(); if (OSFCodeSetRegistry.lookupEntry(nativeSet) == null) throw wrapper.unknownNativeCodeset( new Integer(nativeSet) ) ; List conversionList = new ArrayList(10); // Now process the other values as part of the // conversion code set list. while (stok.hasMoreTokens()) { // decode allows us to specify hex, decimal, etc Integer value = Integer.decode(stok.nextToken()); if (OSFCodeSetRegistry.lookupEntry(value.intValue()) == null) throw wrapper.unknownConversionCodeSet( value ) ; conversionList.add(value); } conversionInts = new int[conversionList.size()]; for (int i = 0; i < conversionInts.length; i++) conversionInts[i] = ((Integer)conversionList.get(i)).intValue(); } catch (NumberFormatException nfe) { throw wrapper.invalidCodeSetNumber( nfe ) ; } catch (NoSuchElementException nsee) { throw wrapper.invalidCodeSetString( nsee, str ) ; } // Otherwise return the CodeSetComponent representing // the given values return new CodeSetComponent(nativeSet, conversionInts); } /** * Code sets for local cases without a connection. */ public static final CodeSetContext LOCAL_CODE_SETS = new CodeSetContext(OSFCodeSetRegistry.ISO_8859_1.getNumber(), OSFCodeSetRegistry.UTF_16.getNumber()); }