1. /*
  2. * @(#)CodeSetComponentInfo.java 1.29 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * Licensed Materials - Property of IBM
  9. * RMI-IIOP v1.0
  10. * Copyright IBM Corp. 1998 1999 All Rights Reserved
  11. *
  12. * US Government Users Restricted Rights - Use, duplication or
  13. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14. */
  15. package com.sun.corba.se.internal.core;
  16. import java.util.StringTokenizer;
  17. import java.util.ArrayList;
  18. import java.util.List;
  19. import org.omg.CORBA.INITIALIZE;
  20. import org.omg.CORBA.CompletionStatus;
  21. import com.sun.corba.se.internal.orbutil.MinorCodes;
  22. public final class CodeSetComponentInfo {
  23. /**
  24. * CodeSetComponent is part of an IOR multi-component profile. Two
  25. * instances constitute a CodeSetComponentInfo (one for char and one
  26. * for wchar data)
  27. */
  28. public static final class CodeSetComponent {
  29. int nativeCodeSet;
  30. int[] conversionCodeSets;
  31. public CodeSetComponent() {}
  32. public CodeSetComponent(int nativeCodeSet, int[] conversionCodeSets) {
  33. this.nativeCodeSet = nativeCodeSet;
  34. if (conversionCodeSets == null)
  35. this.conversionCodeSets = new int[0];
  36. else
  37. this.conversionCodeSets = conversionCodeSets;
  38. }
  39. public void read(MarshalInputStream in) {
  40. nativeCodeSet = in.read_ulong();
  41. int len = in.read_long();
  42. conversionCodeSets = new int[len];
  43. in.read_ulong_array(conversionCodeSets, 0, len);
  44. }
  45. public void write(MarshalOutputStream out) {
  46. out.write_ulong(nativeCodeSet);
  47. out.write_long(conversionCodeSets.length);
  48. out.write_ulong_array(conversionCodeSets, 0, conversionCodeSets.length);
  49. }
  50. public String toString() {
  51. StringBuffer sbuf = new StringBuffer("CodeSetComponent: ");
  52. sbuf.append("native: ");
  53. sbuf.append(Integer.toHexString(nativeCodeSet));
  54. sbuf.append(" conversion: ");
  55. if (conversionCodeSets == null)
  56. sbuf.append("null");
  57. else {
  58. for (int i = 0; i < conversionCodeSets.length; i++) {
  59. sbuf.append(Integer.toHexString(conversionCodeSets[i]));
  60. sbuf.append(' ');
  61. }
  62. }
  63. return sbuf.toString();
  64. }
  65. }
  66. private CodeSetComponent forCharData;
  67. private CodeSetComponent forWCharData;
  68. public String toString() {
  69. StringBuffer sbuf = new StringBuffer("CodeSetComponentInfo: ");
  70. sbuf.append("char data ");
  71. sbuf.append(forCharData.toString());
  72. sbuf.append("wchar data ");
  73. sbuf.append(forWCharData.toString());
  74. return sbuf.toString();
  75. }
  76. public CodeSetComponentInfo() {
  77. forCharData = CodeSetComponentInfo.JAVASOFT_DEFAULT_CODESETS.forCharData;
  78. forWCharData = CodeSetComponentInfo.JAVASOFT_DEFAULT_CODESETS.forWCharData;
  79. }
  80. public CodeSetComponentInfo(CodeSetComponent charData,
  81. CodeSetComponent wcharData) {
  82. forCharData = charData;
  83. forWCharData = wcharData;
  84. }
  85. public void read(MarshalInputStream in) {
  86. forCharData = new CodeSetComponent();
  87. forCharData.read(in);
  88. forWCharData = new CodeSetComponent();
  89. forWCharData.read(in);
  90. }
  91. public void write(MarshalOutputStream out) {
  92. forCharData.write(out);
  93. forWCharData.write(out);
  94. }
  95. public CodeSetComponent getCharComponent() {
  96. return forCharData;
  97. }
  98. public CodeSetComponent getWCharComponent() {
  99. return forWCharData;
  100. }
  101. /**
  102. * CodeSetContext goes in a GIOP service context
  103. */
  104. public static final class CodeSetContext {
  105. private int char_data;
  106. private int wchar_data;
  107. public CodeSetContext() {}
  108. public CodeSetContext(int charEncoding, int wcharEncoding) {
  109. char_data = charEncoding;
  110. wchar_data = wcharEncoding;
  111. }
  112. public void read(MarshalInputStream in) {
  113. char_data = in.read_ulong();
  114. wchar_data = in.read_ulong();
  115. }
  116. public void write(MarshalOutputStream out) {
  117. out.write_ulong(char_data);
  118. out.write_ulong(wchar_data);
  119. }
  120. public int getCharCodeSet() {
  121. return char_data;
  122. }
  123. public int getWCharCodeSet() {
  124. return wchar_data;
  125. }
  126. public String toString() {
  127. StringBuffer sbuf = new StringBuffer();
  128. sbuf.append("CodeSetContext char set: ");
  129. sbuf.append(Integer.toHexString(char_data));
  130. sbuf.append(" wchar set: ");
  131. sbuf.append(Integer.toHexString(wchar_data));
  132. return sbuf.toString();
  133. }
  134. }
  135. /**
  136. * Our default code set scheme is as follows:
  137. *
  138. * char data:
  139. *
  140. * Native code set: ISO 8859-1 (8-bit)
  141. * Conversion sets: UTF-8, ISO 646 (7-bit)
  142. *
  143. * wchar data:
  144. *
  145. * Native code set: UTF-16
  146. * Conversion sets: UCS-2
  147. *
  148. * Pre-Merlin/J2EE 1.3 JavaSoft ORBs listed ISO646 for char and
  149. * UCS-2 for wchar, and provided no conversion sets. They also
  150. * didn't do correct negotiation or provide the fallback sets.
  151. * UCS-2 is still in the conversion list for backwards compatibility.
  152. *
  153. * The fallbacks are UTF-8 for char and UTF-16 for wchar.
  154. *
  155. * In GIOP 1.1, interoperability with wchar is limited to 2 byte fixed
  156. * width encodings since its wchars aren't preceded by a length.
  157. * Thus, I've chosen not to include UTF-8 in the conversion set
  158. * for wchar data.
  159. *
  160. */
  161. public static final CodeSetComponentInfo JAVASOFT_DEFAULT_CODESETS;
  162. static {
  163. CodeSetComponent charData
  164. = new CodeSetComponent(OSFCodeSetRegistry.ISO_8859_1.getNumber(),
  165. new int[] {
  166. OSFCodeSetRegistry.UTF_8.getNumber(),
  167. OSFCodeSetRegistry.ISO_646.getNumber()
  168. });
  169. CodeSetComponent wcharData
  170. = new CodeSetComponent(OSFCodeSetRegistry.UTF_16.getNumber(),
  171. new int[]
  172. {
  173. OSFCodeSetRegistry.UCS_2.getNumber()
  174. });
  175. JAVASOFT_DEFAULT_CODESETS = new CodeSetComponentInfo(charData, wcharData);
  176. }
  177. /**
  178. * Creates a CodeSetComponent from a String which contains a comma
  179. * delimited list of OSF Code Set Registry numbers. An INITIALIZE
  180. * exception is thrown if any of the numbers are not known by our
  181. * registry. Used by corba.ORB init.
  182. *
  183. * The numbers can either be decimal or hex.
  184. */
  185. public static CodeSetComponent createFromString(String str) {
  186. if (str == null || str.length() == 0)
  187. throw new INITIALIZE("Empty or null code set String");
  188. StringTokenizer stok = new StringTokenizer(str, ", ", false);
  189. int nativeSet = 0;
  190. int conversionInts[] = null;
  191. try {
  192. // The first value is the native code set
  193. nativeSet = Integer.decode(stok.nextToken()).intValue();
  194. if (OSFCodeSetRegistry.lookupEntry(nativeSet) == null)
  195. throw new INITIALIZE("Unknown native code set: " + nativeSet);
  196. List conversionList = new ArrayList(10);
  197. // Now process the other values as part of the
  198. // conversion code set list.
  199. while (stok.hasMoreTokens()) {
  200. // decode allows us to specify hex, decimal, etc
  201. Integer value = Integer.decode(stok.nextToken());
  202. if (OSFCodeSetRegistry.lookupEntry(value.intValue()) == null)
  203. throw new INITIALIZE("Unknown conversion code set: "
  204. + value);
  205. conversionList.add(value);
  206. }
  207. conversionInts = new int[conversionList.size()];
  208. for (int i = 0; i < conversionInts.length; i++)
  209. conversionInts[i] = ((Integer)conversionList.get(i)).intValue();
  210. } catch (NumberFormatException nfe) {
  211. throw new INITIALIZE("Invalid code set number: " + nfe.getMessage());
  212. }
  213. // If the entire input string was empty or some other
  214. // error came up, throw an exception
  215. if (nativeSet == 0)
  216. throw new INITIALIZE("Invalid code set String \""
  217. + str
  218. + "\": Requires at least a native code set");
  219. // Otherwise return the CodeSetComponent representing
  220. // the given values
  221. return new CodeSetComponent(nativeSet, conversionInts);
  222. }
  223. /**
  224. * Code sets for local cases without a connection.
  225. */
  226. public static final CodeSetContext LOCAL_CODE_SETS
  227. = new CodeSetContext(OSFCodeSetRegistry.ISO_8859_1.getNumber(),
  228. OSFCodeSetRegistry.UTF_16.getNumber());
  229. }