CDROutputStream_1_1.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25package com.sun.corba.se.impl.encoding; 26 27import org.omg.CORBA.CompletionStatus; 28import com.sun.corba.se.spi.ior.iiop.GIOPVersion; 29import com.sun.corba.se.impl.encoding.CodeSetConversion; 30 31public class CDROutputStream_1_1 extends CDROutputStream_1_0 32{ 33 // This is used to keep indirections working across fragments. When added 34 // to the current bbwi.position(), the result is the current position 35 // in the byte stream without any fragment headers. 36 // 37 // It is equal to the following: 38 // 39 // n = number of buffers (0 is original buffer, 1 is first fragment, etc) 40 // 41 // n == 0, fragmentOffset = 0 42 // 43 // n > 0, fragmentOffset 44 // = sum i=[1,n] { bbwi_i-1_.size - buffer i header length } 45 // 46 protected int fragmentOffset = 0; 47 48 protected void alignAndReserve(int align, int n) { 49 50 // Notice that in 1.1, we won't end a fragment with 51 // alignment padding. We also won't guarantee that 52 // our fragments end on evenly divisible 8 byte 53 // boundaries. There may be alignment 54 // necessary with the header of the next fragment 55 // since the header isn't aligned on an 8 byte 56 // boundary, so we have to calculate it twice. 57 58 int alignment = computeAlignment(align); 59 60 if (bbwi.position() + n + alignment > bbwi.buflen) { 61 grow(align, n); 62 63 // Must recompute the alignment after a grow. 64 // In the case of fragmentation, the alignment 65 // calculation may no longer be correct. 66 67 // People shouldn't be able to set their fragment 68 // sizes so small that the fragment header plus 69 // this alignment fills the entire buffer. 70 alignment = computeAlignment(align); 71 } 72 73 bbwi.position(bbwi.position() + alignment); 74 } 75 76 protected void grow(int align, int n) { 77 // Save the current size for possible post-fragmentation calculation 78 int oldSize = bbwi.position(); 79 80 super.grow(align, n); 81 82 // At this point, if we fragmented, we should have a ByteBufferWithInfo 83 // with the fragment header already marshalled. The size and length fields 84 // should be updated accordingly, and the fragmented flag should be set. 85 if (bbwi.fragmented) { 86 87 // Clear the flag 88 bbwi.fragmented = false; 89 90 // Update fragmentOffset so indirections work properly. 91 // At this point, oldSize is the entire length of the 92 // previous buffer. bbwi.position() is the length of the 93 // fragment header of this buffer. 94 fragmentOffset += (oldSize - bbwi.position()); 95 } 96 } 97 98 public int get_offset() { 99 return bbwi.position() + fragmentOffset; 100 } 101 102 public GIOPVersion getGIOPVersion() { 103 return GIOPVersion.V1_1; 104 } 105 106 public void write_wchar(char x) 107 { 108 // In GIOP 1.1, interoperability with wchar is limited 109 // to 2 byte fixed width encodings. CORBA formal 99-10-07 15.3.1.6. 110 // Note that the following code prohibits UTF-16 with a byte 111 // order marker (which would result in 4 bytes). 112 CodeSetConversion.CTBConverter converter = getWCharConverter(); 113 114 converter.convert(x); 115 116 if (converter.getNumBytes() != 2) 117 throw wrapper.badGiop11Ctb(CompletionStatus.COMPLETED_MAYBE); 118 119 alignAndReserve(converter.getAlignment(), 120 converter.getNumBytes()); 121 122 parent.write_octet_array(converter.getBytes(), 123 0, 124 converter.getNumBytes()); 125 } 126 127 public void write_wstring(String value) 128 { 129 if (value == null) { 130 throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE); 131 } 132 133 // The length is the number of code points (which are 2 bytes each) 134 // including the 2 byte null. See CORBA formal 99-10-07 15.3.2.7. 135 136 int len = value.length() + 1; 137 138 write_long(len); 139 140 CodeSetConversion.CTBConverter converter = getWCharConverter(); 141 142 converter.convert(value); 143 144 internalWriteOctetArray(converter.getBytes(), 0, converter.getNumBytes()); 145 146 // Write the 2 byte null ending 147 write_short((short)0); 148 } 149} 150