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