CDRInputStream_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 com.sun.corba.se.spi.ior.iiop.GIOPVersion; 28 29public class CDRInputStream_1_1 extends CDRInputStream_1_0 30{ 31 // See notes in CDROutputStream 32 protected int fragmentOffset = 0; 33 34 public GIOPVersion getGIOPVersion() { 35 return GIOPVersion.V1_1; 36 } 37 38 // Template method 39 public CDRInputStreamBase dup() { 40 CDRInputStreamBase result = super.dup(); 41 42 ((CDRInputStream_1_1)result).fragmentOffset = this.fragmentOffset; 43 44 return result; 45 } 46 47 protected int get_offset() { 48 return bbwi.position() + fragmentOffset; 49 } 50 51 protected void alignAndCheck(int align, int n) { 52 53 54 checkBlockLength(align, n); 55 56 // WARNING: Must compute real alignment after calling 57 // checkBlockLength since it may move the position 58 int alignment = computeAlignment(bbwi.position(), align); 59 60 if (bbwi.position() + n + alignment > bbwi.buflen) { 61 62 // Some other ORBs may have found a way to send 1.1 63 // fragments which put alignment bytes at the end 64 // of a fragment 65 if (bbwi.position() + alignment == bbwi.buflen) 66 { 67 bbwi.position(bbwi.position() + alignment); 68 } 69 70 grow(align, n); 71 72 // We must recalculate the alignment after a possible 73 // fragmentation since the new bbwi.position() (after the header) 74 // may require a different alignment. 75 76 alignment = computeAlignment(bbwi.position(), align); 77 } 78 79 bbwi.position(bbwi.position() + alignment); 80 } 81 82 // 83 // This can be overridden.... 84 // 85 protected void grow(int align, int n) { 86 87 bbwi.needed = n; 88 89 // Save the size of the current buffer for 90 // possible fragmentOffset calculation 91 int oldSize = bbwi.position(); 92 93 bbwi = bufferManagerRead.underflow(bbwi); 94 95 if (bbwi.fragmented) { 96 97 // By this point we should be guaranteed to have 98 // a new fragment whose header has already been 99 // unmarshalled. bbwi.position() should point to the 100 // end of the header. 101 fragmentOffset += (oldSize - bbwi.position()); 102 103 markAndResetHandler.fragmentationOccured(bbwi); 104 105 // Clear the flag 106 bbwi.fragmented = false; 107 } 108 } 109 110 // Mark/reset --------------------------------------- 111 112 private class FragmentableStreamMemento extends StreamMemento 113 { 114 private int fragmentOffset_; 115 116 public FragmentableStreamMemento() 117 { 118 super(); 119 120 fragmentOffset_ = fragmentOffset; 121 } 122 } 123 124 public java.lang.Object createStreamMemento() { 125 return new FragmentableStreamMemento(); 126 } 127 128 public void restoreInternalState(java.lang.Object streamMemento) 129 { 130 super.restoreInternalState(streamMemento); 131 132 fragmentOffset 133 = ((FragmentableStreamMemento)streamMemento).fragmentOffset_; 134 } 135 136 // -------------------------------------------------- 137 138 public char read_wchar() { 139 // In GIOP 1.1, interoperability with wchar is limited 140 // to 2 byte fixed width encodings. CORBA formal 99-10-07 15.3.1.6. 141 // WARNING: For UTF-16, this means that there can be no 142 // byte order marker, so it must default to big endian! 143 alignAndCheck(2, 2); 144 145 // Because of the alignAndCheck, we should be guaranteed 146 // 2 bytes of real data. 147 char[] result = getConvertedChars(2, getWCharConverter()); 148 149 // Did the provided bytes convert to more than one 150 // character? This may come up as more unicode values are 151 // assigned, and a single 16 bit Java char isn't enough. 152 // Better to use strings for i18n purposes. 153 if (getWCharConverter().getNumChars() > 1) 154 throw wrapper.btcResultMoreThanOneChar() ; 155 156 return result[0]; 157 } 158 159 public String read_wstring() { 160 // In GIOP 1.1, interoperability with wchar is limited 161 // to 2 byte fixed width encodings. CORBA formal 99-10-07 15.3.1.6. 162 int len = read_long(); 163 164 // Workaround for ORBs which send string lengths of 165 // zero to mean empty string. 166 // 167 // IMPORTANT: Do not replace 'new String("")' with "", it may result 168 // in a Serialization bug (See serialization.zerolengthstring) and 169 // bug id: 4728756 for details 170 if (len == 0) 171 return new String(""); 172 173 checkForNegativeLength(len); 174 175 // Don't include the two byte null for the 176 // following computations. Remember that since we're limited 177 // to a 2 byte fixed width code set, the "length" was the 178 // number of such 2 byte code points plus a 2 byte null. 179 len = len - 1; 180 181 char[] result = getConvertedChars(len * 2, getWCharConverter()); 182 183 // Skip over the 2 byte null 184 read_short(); 185 186 return new String(result, 0, getWCharConverter().getNumChars()); 187 } 188 189} 190