1. /*
  2. * @(#)CDROutputStream_1_1.java 1.15 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. package com.sun.corba.se.internal.iiop;
  8. import org.omg.CORBA.DATA_CONVERSION;
  9. import org.omg.CORBA.BAD_PARAM;
  10. import org.omg.CORBA.CompletionStatus;
  11. import com.sun.corba.se.internal.core.GIOPVersion;
  12. import com.sun.corba.se.internal.orbutil.MinorCodes;
  13. import com.sun.corba.se.internal.core.CodeSetConversion;
  14. public class CDROutputStream_1_1 extends CDROutputStream_1_0
  15. {
  16. // This is used to keep indirections working across fragments. When added
  17. // to the current bbwi.index, the result is the current position
  18. // in the byte stream without any fragment headers.
  19. //
  20. // It is equal to the following:
  21. //
  22. // n = number of buffers (0 is original buffer, 1 is first fragment, etc)
  23. //
  24. // n == 0, fragmentOffset = 0
  25. //
  26. // n > 0, fragmentOffset
  27. // = sum i=[1,n] { bbwi_i-1_.size - buffer i header length }
  28. //
  29. protected int fragmentOffset = 0;
  30. protected void alignAndReserve(int align, int n) {
  31. // Notice that in 1.1, we won't end a fragment with
  32. // alignment padding. We also won't guarantee that
  33. // our fragments end on evenly divisible 8 byte
  34. // boundaries. There may be alignment
  35. // necessary with the header of the next fragment
  36. // since the header isn't aligned on an 8 byte
  37. // boundary, so we have to calculate it twice.
  38. int alignment = computeAlignment(align);
  39. if (bbwi.index + n + alignment > bbwi.buflen) {
  40. grow(align, n);
  41. // Must recompute the alignment after a grow.
  42. // In the case of fragmentation, the alignment
  43. // calculation may no longer be correct.
  44. // People shouldn't be able to set their fragment
  45. // sizes so small that the fragment header plus
  46. // this alignment fills the entire buffer.
  47. alignment = computeAlignment(align);
  48. }
  49. bbwi.index += alignment;
  50. }
  51. protected void grow(int align, int n) {
  52. // Save the current size for possible post-fragmentation calculation
  53. int oldSize = bbwi.index;
  54. super.grow(align, n);
  55. // At this point, if we fragmented, we should have a ByteBufferWithInfo
  56. // with the fragment header already marshalled. The size and length fields
  57. // should be updated accordingly, and the fragmented flag should be set.
  58. if (bbwi.fragmented) {
  59. // Clear the flag
  60. bbwi.fragmented = false;
  61. // Update fragmentOffset so indirections work properly.
  62. // At this point, oldSize is the entire length of the
  63. // previous buffer. bbwi.index is the length of the
  64. // fragment header of this buffer.
  65. fragmentOffset += (oldSize - bbwi.index);
  66. }
  67. }
  68. public int get_offset() {
  69. return bbwi.index + fragmentOffset;
  70. }
  71. public GIOPVersion getGIOPVersion() {
  72. return GIOPVersion.V1_1;
  73. }
  74. public void write_wchar(char x)
  75. {
  76. // In GIOP 1.1, interoperability with wchar is limited
  77. // to 2 byte fixed width encodings. CORBA formal 99-10-07 15.3.1.6.
  78. // Note that the following code prohibits UTF-16 with a byte
  79. // order marker (which would result in 4 bytes).
  80. CodeSetConversion.CTBConverter converter = getWCharConverter();
  81. converter.convert(x);
  82. if (converter.getNumBytes() != 2)
  83. throw new DATA_CONVERSION(MinorCodes.BAD_GIOP_1_1_CTB,
  84. CompletionStatus.COMPLETED_MAYBE);
  85. alignAndReserve(converter.getAlignment(),
  86. converter.getNumBytes());
  87. parent.write_octet_array(converter.getBytes(),
  88. 0,
  89. converter.getNumBytes());
  90. }
  91. public void write_wstring(String value)
  92. {
  93. if (value == null) {
  94. throw new BAD_PARAM(com.sun.corba.se.internal.orbutil.MinorCodes.NULL_PARAM,
  95. CompletionStatus.COMPLETED_MAYBE);
  96. }
  97. // The length is the number of code points (which are 2 bytes each)
  98. // including the 2 byte null. See CORBA formal 99-10-07 15.3.2.7.
  99. int len = value.length() + 1;
  100. write_long(len);
  101. CodeSetConversion.CTBConverter converter = getWCharConverter();
  102. converter.convert(value);
  103. internalWriteOctetArray(converter.getBytes(), 0, converter.getNumBytes());
  104. // Write the 2 byte null ending
  105. write_short((short)0);
  106. }
  107. }