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